2

为了区分内部用户和外部用户,我在 scriplet 标记中使用了 java 正则表达式,代码如下:

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 
}   

如果输入为 166.41.8.2,则 IP 地址被正确识别为内部 IP 如果输入为 12.16.2.1 或 12.22.12.3,则 IP 地址未被正确识别为内部 IP。我想这与匹配模式与 2 个“X”有关。任何人都可以识别模式匹配的问题吗?或者可以推荐一种匹配 IP 地址模式的最佳方法?

4

3 回答 3

3

2 处更正:

  1. 句号.应该被转义,否则它意味着任何字符
  2. \\d在您的replaceAll通话中需要双重转义,因为这最终成为您的最终正则表达式。

这是工作代码:

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"); 

备选方案:

由于您在internalIPs.replaceAll调用中并没有真正使用任何正则表达式,因此最好使用String#replace方法(不支持正则表达式),这样就不需要双重转义。所以只需像这样使用:

Pattern p = Pattern.compile("^(?:" + internalIPs.replace("X",
                            "(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])")+")$");
于 2012-05-08T20:58:55.880 回答
1

我不知道这是否是原因,但请尝试将.您的内部 IP 声明中的\.

.in regexp 用于匹配所有内容。

于 2012-05-08T20:56:32.370 回答
1

我建议不要使用正则表达式执行过于复杂的 IP 体操。

"([0-9]{1,3}.){3}[0-9]{1,3})" 进行一般检查是可以的,那么我会做一个

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

其次是 Integer.parseInt 和范围检查或值比较。

于 2012-05-08T21:03:01.173 回答