13

I am facing problem while matching input string with Regex. I want to validate input number is between 0-255 and length should be up to 3 characters long. code is working fine but when I input 000000 up to any length is shows true instead false.

Here is my code :-

String IP = "000000000000000";
        System.out.println(IP.matches("(0*(?:[0-9][0-9]?|[0-2][0-5][0-5]))"));
Salman A
  • 262,204
  • 82
  • 430
  • 521
user2965598
  • 187
  • 1
  • 2
  • 8
  • 2
    Why do you want to do this using regular expressions? – Paul Jul 28 '15 at 19:27
  • If you need leading zeros, try this: `"((\\d{1,2}|[01]\\d{1,2}|[0-2][0-4]\\d|25[0-5])\\.){3}(\\d{1,2}|[01]\\d{1,2}|[0-2][0-4]\\d|25[0-5])"` – RichArt Feb 23 '18 at 20:25
  • Why would you want to execute about a megabyte of regex code instead of a simple conversion to binary and then a single comparison operator? – user207421 Feb 23 '18 at 20:32
  • 1
    One ends up needing to define regexps like this because one is using someone else's bonkers idea of how to implement an IP filter. I'm looking at you, Micronaut Security! – Ben Ketteridge Jul 22 '20 at 14:32

12 Answers12

14

Tested this:

static String pattern = "^(([0-1]?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])\\.){3}([0-1]?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5]){1}$";

It works for the following:

  • IP Addresses xxx.xxx.xxx.xxx / xx.xx.xx.xx / x.x.x.x / mix of these.
  • Leading zeros are allowed.
  • Range 0-255 / maximum 3 digts.
BladeMight
  • 2,670
  • 2
  • 21
  • 35
Leo
  • 151
  • 1
  • 3
9

You may use this regex:

boolean valid = IP.matches("^(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])$");

// since .matches expects complete match you can omit anchors
boolean valid = IP.matches("(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])");

RegEx Demo

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    Thanks anubhava. It's working perfect now. Also can you suggest me better source to learn regex beyond the basics. – user2965598 Jul 28 '15 at 18:22
  • 1
    I am a big fan of http://www.regular-expressions.info and for Java http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html – anubhava Jul 28 '15 at 18:23
  • 1
    Just a little bit addition: You could make your regexp 1 tag shorter by adding 1? front of your 2 digit match, as 0-99/ 100 -199 only an optional 1 is the difference, and you could take out the 1[0-9]{2} part – zolo Jul 28 '15 at 19:43
  • Thanks @zolo yes `\b(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\b` will a bit smaller (edited) – anubhava Jul 28 '15 at 19:49
  • As shown in the demo link, this pattern (I assume incorrectly) matches two-digit numbers that have a leading zero like: `01` and `09`. – mickmackusa Jul 12 '17 at 09:08
  • Your new adjusted pattern doesn't match `0`. I am not challenging you on this to be rude, I am waiting for you to pull a regex rabbit out of a hat and show me something crazy awesome that I've never considered. [respect] – mickmackusa Jul 12 '17 at 12:22
  • @mickmackusa: Use this one: `\b([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\b` – anubhava Jul 12 '17 at 12:44
  • 1
    How about we accept all leading 0's too: \b0*(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\b and then if you want to verify a valid IPv4 address you can use the following: (?:0*(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){1,3}0*(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5]) *** ( Remember 127.1 is the same as 127.0.0.1 so 127.1 is a valid IP address ) *** – Johan G Nov 16 '17 at 07:17
  • 1
    so with @zolo's suggestion (`(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])`) the regex is less strict as pointed by @mickmackusa and allows two-digit numbers that have leading zeros. @anubhava's alternate solution `([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])` will provide a stricter regex which doesn't allow two-digit numbers with leading zeros. – kimbaudi Aug 22 '19 at 18:41
  • @anubhava this did not work for `000` , I have modified your regex as below to support this `\\b([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\b` – Asanka Siriwardena Dec 13 '21 at 16:42
  • Just change `1?[0-9]{1,2}` to `[0-9]{1,3}` to allow `000` – anubhava Dec 13 '21 at 16:46
  • @anubhava, your approach says this is valid IP: 'asdf1.1.dd1.dd1' – Dmitry Shevkoplyas Jan 16 '23 at 15:30
  • No it doesn't. Regex in `.matches` is automatically anchored so it effectively becomes `^(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])$` and that won't match. – anubhava Jan 16 '23 at 16:59
8

You can use this pattern which matches "0", "1", ... "255":

"([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"

Demo on Ideone

Salman A
  • 262,204
  • 82
  • 430
  • 521
  • 1
    You are correct mentioning each case, however you can simplify it. 0-199 you could check with one section, 200-249 the other, 250-255 is the third one. Shorter, more simple, and faster. – zolo Jul 28 '15 at 19:51
  • 1
    I found this solution at https://www.regular-expressions.info/numericranges.html with much more in-depth explanation. Also, you could shorten this regex to `([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])` as can be seen by @anubhava's alternate solution. Basically, you are replacing `1[0-9][0-9]` with `1[0-9]{2}`. – kimbaudi Aug 22 '19 at 18:43
  • This pattern is more appropriate because it also avoids "00" compared to the accepted pattern. – Farzad Feb 15 '23 at 21:41
3

Using boundary tags to ensure only (0 to 255) numbers is matched, the optimized pattern that I have to offer is:

\b(?:1\d{2}|2[0-4]\d|[1-9]?\d|25[0-5])\b

Pattern Demo (in PHP/PCRE to show step count)

4010 steps when checking a list from 0 to 256.

This pattern will not match 01 or 001. (no match on one or more leading zeros)

Considerations:

  1. Use quantifiers on consecutive duplicate characters.
  2. Organize the alternatives not in sequential order (single-digit, double-digit, 100's, under-249, 250-255) but with quickest mis-matches first.
  3. Avoid non-essential capture (or non-capture) groups. (despite seeming logical to condense the "two hundreds" portion of the pattern)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
1

Please try this

"^(((\d|0\d|00\d|\d{2}|0\d{2}|1\d{2}|2[0-4]\d|2[0-5]{2})\.){3})(\d|0\d|00\d|\d{2}|0\d{2}|1\d{2}|2[0-4]\d|2[0-5]{2})$"

It works also with leading zeroes

BR1COP
  • 321
  • 2
  • 5
0
boolean valid = IP.matches("(0?[0-9]{1,2}|1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])");
Etienne Lawlor
  • 6,817
  • 18
  • 77
  • 89
0

Complete ip inet4 match :

JS

/(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])/g.exec(myIp);

https://regex101.com/r/tU3gC3/12

Minified :

/(1?(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])/g.exec(myIp);

https://regex101.com/r/tU3gC3/13

0

This will work for following pattern and ip containing initial zeros e.g: 023.45.12.56

pattern=(\\d{1,2}|(0|1)\\d{2}|2[0-4]\\d|25[0-5]);
Saurabh
  • 7,525
  • 4
  • 45
  • 46
0

If you need leading zeros, try this:

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

It satisfies following conditions: IP address is a string in the form "A.B.C.D", where the value of A, B, C, and D may range from 0 to 255. Leading zeros are allowed. The length of A, B, C, or D can't be greater than 3.

Maybe somebody can help with additional simplifying?

RichArt
  • 1,534
  • 18
  • 35
0

If you want to validate ip4 with 'ip/mask', so regex looks like this:

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\/([0-9]|[1-2][0-9]|3[0-2]))$

Just ip

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

JS code to test it

function isMatchByRegexp(stringToValidate, regexp) {
var re = new RegExp(regexp);
return re.test(stringToValidate);
}
0

(2[0-4][0-9])|([0-1]?[0-9]?[0-9])

To match 0 to 249 specifically

0

You can simplify it by thinking in four conditions that might happen

 String zeroTo255 = "((0|1)\\d{2}|2[0-4]\\d|25[0-5]|\\d{1,2})";
 String validIpPattern = zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255;
  1. (0|1)\d{2} catches any three digit number starting with 0 or 1.
  2. 2[0-4]\d catches numbers between 200 and 249.
  3. 25[0-5] catches numbers between 250 and 255.
  4. \d{1,2} catches any one or two digit number

you can test it in https://regexr.com/

To test it here in regexr you need to remove one backslash

(\\d --> \d)

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

Note that \d represents digits in regular expressions, same as [0-9]

naib khan
  • 928
  • 9
  • 16