1

So this is the regex I've made: ^(([01]?\d{1,2})|(2(([0-4]\d)|(5[0-5])))\.){3}(([01]?\d{1,2})|(2(([0-4]\d)|(5[0-5]))))$

I have used several sites to break it down and it seems that it should work, but it doesn't. The desired result is to match any IPv4 - four numbers between 0 and 255 delimited by dots.

As an example, 1.1.1.1 won't give you a match. The purpose of this question is not to find out a regex for IPv4 address, but to find out why this one, which seems correct, is not.

Andrew Vershinin
  • 1,958
  • 11
  • 16

2 Answers2

3

The literal . is only part of the 200-255 section of the capture group: railroad diagram.

Here's (([01]?\d{1,2})|(2([0-4]\d)|(5[0-5]))\.) formatted differently to help you spot the reason:

(
    ([01]?\d{1,2})
    |
    (2([0-4]\d)|(5[0-5])) \.
)

You're matching 0-199 or 200-255 with a dot. The dot is conditional on matching 200-255.

Additionally, as @SebastianProske pointed out, 2([0-4]\d)|(5[0-5]) matches 200-249 or 50-55, not 200-255.

You can fix your regex by adding capturing groups, but ultimately I would recommend not reinventing the wheel and using A) a pre-existing regex solution or B) parse the IPv4 address by splitting on dots. The latter method being easier to read and understand.

Mr. Llama
  • 20,202
  • 2
  • 62
  • 115
  • 1
    There is no 200-255 section, it's a 200-249 and 50-55 section. – Sebastian Proske Dec 06 '16 at 17:59
  • @SebastianProske - Oof, that'll need fixing too. I'll edit that in. – Mr. Llama Dec 06 '16 at 18:00
  • @SebastianProske I have corrected the expression. I've enclosed the OR clause in a group, but it doesn't makes the expression to match correctly. – Andrew Vershinin Dec 06 '16 at 18:00
  • @AndrewVershinin - You'll need to add a group to fix the 200-255 issue as well as add a group to fix the dot issue. You'll need to fix the 200-255 issue in both places it appears. – Mr. Llama Dec 06 '16 at 18:04
  • @Mr.Llama Thank you. Enclosing the part before the dot makes it work. As the question states, I can use Google. I just wanted to realise why this solution is not correct. – Andrew Vershinin Dec 06 '16 at 18:10
0

to fix yours up, just account for the "decimal" after each of the first three groups:

((2[0-4]\d|25[0-5]|[01]?\d{1,2})\.){3}(2[0-4]\d|25[0-5]|[01]?\d{1,2})

(*note that I reversed the order of the 2xx vs 1xx tests as well - prefer SPECIAL|...|NORMAL, or more restrictive first, when using alternations like this)

see it in action

Scott Weaver
  • 7,192
  • 2
  • 31
  • 43