neelmeg
neelmeg

Reputation: 2509

java regular expression IP address pattern match

In order to distinguish internal and external users, I'm using java regular expressions within scriplet tags and the code is below:

String ipAddress  = request.getHeader("iv-remote-address");

String internalIPs = 
"166.41.8.X" + "|" +"12.16.X.X" + "|" +"12.22.X.X" + "|" +"132.23.X.X" + "|";

Pattern p = Pattern.compile("^(?:"+internalIPs.replaceAll("X", "(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])")+")$");

Matcher m = p.matcher(ipAddress);

if (m.matches())
{
    //print internal IP     
} else{
    //print external IP 
}   

If the input is 166.41.8.2, the IP address is correctly identified as internal IP if the input is 12.16.2.1 or 12.22.12.3, the IP address is not correctly identified as internal IP. I guess that has to do with matching pattern with 2 "X"s. Can anybody identify the issue with pattern matching? Or could recommend a best way of matching pattern of IP addresses?

Upvotes: 2

Views: 6412

Answers (3)

anubhava
anubhava

Reputation: 784898

2 corrections:

  1. period . should be escaped otherwise it means any character
  2. \\d in your replaceAll call needs to be doubly escaped since that eventually becomes your final regex.

Here is the working code:

String ipAddress  = "12.16.2.1";
String internalIPs = 
"166\\.41\\.8\\.X" + "|" +"12\\.16\\.X\\.X" + "|" +
"12\\.22\\.X\\.X" + "|" +"132\\.23\\.X\\.X" + "|";

Pattern p = Pattern.compile("^(?:"+internalIPs.replaceAll("X",
                            "(?:\\\\d{1,2}|1\\\\d{2}|2[0-4]\\\\d|25[0-5])")+")$");

//System.out.println(p.pattern());

Matcher m = p.matcher(ipAddress);
if (m.matches())
    System.out.println("print internal IP"); // gets printed  
else
    System.out.println("print external IP"); 

Alternative Option:

Since you are not really using any regex in the internalIPs.replaceAll call it is better to use String#replace method (which doesn't support regex) and then there would be no need for double-escaping. So just use like this:

Pattern p = Pattern.compile("^(?:" + internalIPs.replace("X",
                            "(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])")+")$");

Upvotes: 3

user unknown
user unknown

Reputation: 36229

I would suggest not to perform too complicated IP gymnastics with regexs.

"([0-9]{1,3}.){3}[0-9]{1,3})" for a general check is okay, then I would do an

"166.41.8.123".split ("\\.")

followed by Integer.parseInt and range checks or value comparison.

Upvotes: 1

Rafael
Rafael

Reputation: 2443

I don know if this is the cause, but try changing the . in your internal IPs declaration to \.

. in regexp is used to match everything.

Upvotes: 1

Related Questions