cieunteung
cieunteung

Reputation: 1793

RegEx for Capturing Number Patterns not Followed by Other Characters

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

Upvotes: 2

Views: 63

Answers (3)

user557597
user557597

Reputation:

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* : )

Upvotes: 1

DocMax
DocMax

Reputation: 12164

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:])

Upvotes: 2

Albondi
Albondi

Reputation: 1151

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.

Upvotes: 0

Related Questions