2

I'm using C# and want to capture IP:PORT with Regex but how to make it not match if after PORT the character is : ?

test it here

Pattern:

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

Expexted result

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
Emma
  • 27,428
  • 11
  • 44
  • 69
cieunteung
  • 1,725
  • 13
  • 16

3 Answers3

2

The problem is that your port expression (\d{2,5}) is not grabbing all of the digits. In the unexpectedly-passing expression, if you look at the match groups, they are 1.22.234.255 and 818 (not 8181). The expression does reject 1.22.234.255:8181 because it is followed by a :, but the then considers a 3-digit port and accepts 1.22.234.255:818 because the next character is a 1 and not a :.

One way to compensate for this is by changing your pattern to reject both colons and digits:

(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})[:\s]+(\d{2,5})(?![0-9:])
DocMax
  • 12,094
  • 7
  • 44
  • 44
1

This regex works for all cases

(\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

Readable version

 (                             # (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* : )
0

Try using two different regular expressions, it will be simpler

Expression 1 for spaces:

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

Expression 2 no spaces, you must make sure it has an EOL character or /m modifier if you have multiple lines:

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

Match against any of the two and merge the results.

Albondi
  • 1,141
  • 1
  • 8
  • 19
  • thanks, it random string I cannot use `^$` because the value could be in the middle and separator should be colon or space `[:\s]` – cieunteung May 15 '19 at 15:36