我知道java的基础知识,但我对正则表达式或模式不太熟悉,所以请原谅我,如果我问一些超级简单的东西.. 我正在编写一种检测IP地址和主机名的方法。我使用了这个问题的正则表达式here。我遇到的问题是没有符号的句子被计为主机名
继承我的代码:
Pattern validHostname = Pattern.compile("^(([a-z]|[a-z][a-z0-9-]*[a-z0-9]).)*([a-z]|[a-z][a-z0-9-]*[a-z0-9])$",Pattern.CASE_INSENSITIVE);
Pattern validIpAddress = Pattern.compile("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])([:]\\d\\d*\\d*\\d*\\d*)*$",Pattern.CASE_INSENSITIVE);
String msg = c.getMessage();
boolean found=false;
//Randomly picks from a list to replace the detected ip/hostname
int rand=(int)(Math.random()*whitelisted.size());
String replace=whitelisted.get(rand);
Matcher matchIP = validIpAddress.matcher(msg);
Matcher matchHost = validHostname.matcher(msg);
while(matchIP.find()){
if(adreplace)
msg=msg.replace(matchIP.group(),replace);
else
msg=msg.replace(matchIP.group(),"");
found=true;
c.setMessage(msg);
}
while(matchHost.find()){
if(adreplace)
msg=msg.replace(matchHost.group(),replace);
else
msg=msg.replace(matchHost.group(),"");
found=true;
c.setMessage(msg);
}
return c;
答案 0 :(得分:2)
如果没有示例文本和所需的输出,我会尽力回答您的问题。
我会像这样重写主机名表达式:
答: ^(?:[a-z][a-z0-9-]*[a-z0-9](?=\.[a-z]|$)\.?)+$
会允许使用abcdefg
B: ^(?=(?:.*?\.){2})(?:[a-z][a-z0-9-]*[a-z0-9](?=\.[a-z]|$)\.?)+$
要求字符串至少包含两个句点abc.defg.com
。这将不允许句点出现在开头或结尾或连续句点。前瞻{2}
内的数字描述了必须出现的最小点数。您可以根据需要更改此数字。
^
匹配字符串锚的开头(?:
启动非捕获组可提高性能[a-z][a-z0-9-]*[a-z0-9]
匹配文本,取自原始表达(?=\.[a-z]|$)
向前看,看下一个字符是一个点后跟一个a-z字符,还是字符串的结尾\.?
消耗一个点(如果存在))
关闭捕获组+
要求捕获组的内容存在1次或更多次$
匹配字符串锚的结尾主机名:
A Allows host name without dots
B Requires host name to have a dot
Live Demo with a sentence with no symbols
我也会重写IP表达式
^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(?::\d*)?$
这里的主要区别是我:
\d*\d*\d*\d*\d*\d*
等同于\d*
[:]
更改为单个字符:
(
... )
转变为非捕获群(?
... )
,效果更好。