用于捕获不跟其他字符的数字模式的 RegEx

RegEx for Capturing Number Patterns not Followed by Other Characters

我正在使用 C# 并想使用 Regex 捕获 IP:PORT 但如果 PORT 之后的字符是 : 如何使其不匹配?

测试一下 here

模式:

(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[:\s]+(\d{2,5})(?!:)

扩展结果

1.22.234.255:8181:u:p // true, it should be false
   1.22.234.255:80 // true
  1.22.234.255    8080 // true
 dddd1.22.234.255       80808 // true

尝试使用两个不同的正则表达式,会更简单

空格的表达式 1:

(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\d{2,5})

表达式 2 没有空格,如果有多行,必须确保它有 EOL 字符或 /m 修饰符:

(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:(\d{2,5})$

匹配两者中的任何一个并合并结果。

问题是您的端口表达式 (\d{2,5}) 没有获取所有数字。在 unexpectedly-passing 表达式中,如果您查看匹配组,它们是 1.22.234.255818 不是 8181)。该表达式确实拒绝了 1.22.234.255:8181,因为它后面跟着一个 :,但是 then 考虑了一个 3 位数的端口并接受了 1.22.234.255:818,因为下一个字符是 1 而不是:.

对此进行补偿的一种方法是更改​​您的模式以拒绝冒号和数字:

(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[:\s]+(\d{2,5})(?![0-9:])

此正则表达式适用于所有情况

(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*(?::\s*)?(?<!\d)(\d{2,5})(?!\d|\s*:)

https://regex101.com/r/5faUcx/1

可读版本

 (                             # (1 start), IP
      \d{1,3} \.
      \d{1,3} \.
      \d{1,3} \.
      \d{1,3} 
 )                             # (1 end)

 \s* 
 (?: : \s* )?
 (?<! \d )

 ( \d{2,5} )                   # (2), Port
 (?! \d | \s* : )