0

I've made this regex to check whether a string is a valid IP, including checking if each octel is between 0-255 (more specifically, it checks if it's between 0-199 OR 200-249 OR 250-255)

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

A more simple way of looking at it is:

(pattern\.){3}pattern

which matches pattern.pattern.pattern.pattern such that pattern is a number between 0 and 255.

I was wondering if there's a shorter way of writing this regex, such that pattern only has to be written once, while not compromising the accuracy of the regex, like (pattern\.?){4} does.

edit

Looks like this: ^pattern($|\.(?!$)){4}$ does exactly what I'm looking for.

Taken from: https://stackoverflow.com/a/28446132/4526483

Community
  • 1
  • 1
Knowbody
  • 66
  • 5
  • 1
    your regex accepts 00, but not 000. why? – njzk2 Feb 15 '16 at 23:44
  • 2
    I don't think I've seen anyone write an IP address with multi-digit zeros in any of the octels – Knowbody Feb 15 '16 at 23:47
  • Doesn't mean it's not valid though. – miken32 Feb 15 '16 at 23:55
  • I suppose if you really were expecting them, you could use `(0|1)?\d?\d` instead of `1?\d?\d` – Knowbody Feb 15 '16 at 23:56
  • 2
    Possible duplicate of [Regular expression for IP Address Validation](http://stackoverflow.com/questions/10006459/regular-expression-for-ip-address-validation) – miken32 Feb 15 '16 at 23:57
  • 1
    IP address validation is very complex subject and is next to impossible to cover in one regex. Please see this. https://en.wikipedia.org/wiki/IPv4 – Saleem Feb 15 '16 at 23:58
  • 1
    Specifically, sounds like you're looking for this answer: http://stackoverflow.com/a/28445732/1255289 – miken32 Feb 15 '16 at 23:58
  • Assuming the pattern was just `4` then `'^(4((?=$)|.(?!$))){4}$'` matches the start of a string, 4 at the end of the string or a dot which isn't at the end, four times, then the end of string. Because I don't think it's possible to match the end of string more than once, this seems to constrain it to `4.4.4.4` precisely. Your pattern is different, your regex engine might not support lookarounds. Ymmv. – TessellatingHeckler Feb 15 '16 at 23:59

1 Answers1

0

Actually yes! Start with a slightly too-flexible regex that has complex pattern once:

(pattern\.?){4}

Then apply an assertion to lock down the dots:

(?=(\d+\.){3}\d+([^.\d]|$))(pattern\.?){4}

The full regex would then be:

(?=(\d+\.){3}\d+([^.\d]|$)(1?\d?\d|2[0-4]\d|25[0-5])\.){4}

If a dot is OK to immediately follow the ip, remove the dot from the character class in the look ahead.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Looks like that does make it a little bit shorter: `(?=(\\d+\.){3}\\d+)((1?\d?\d|2[0-4]\d|25[0-5])\.?){4}` – Knowbody Feb 16 '16 at 00:06
  • @knowbody if you're not fussy about what follows you can even delete entirely the final part `([^.\d]|$)` – Bohemian Feb 16 '16 at 00:08