【发布时间】:2013-11-08 18:27:48
【问题描述】:
*EDIT2 正则表达式不一定是解决这个问题的最佳方法。我所要做的就是验证 data[i] 不包含“#”字符。*
编辑我忘了说这是为了验证。我确实用分号拆分字符串,但是这些是我需要解析的更大文件的一部分,显然我不希望我的解析器在尝试拆分不包含“;”的字符串时中断
我想要一个正则表达式来匹配以下示例字符串。我已经用单个表达式(减去分号)完成了所有这些操作,但是我是一个正则表达式新手,所以在这个表达式上遇到了麻烦。
2013/11/06 15:34:01;website.some.net;80;43.121.103.95
2013/11/06 15:45:15;site.test.com;8080;43.22.118.51
分解一下
date 空格 HH:MM:SS 分号 URI 分号 PortNumber 分号 IPv4Address
这是我过去用于单个组件的正则表达式。
日期和时间 - (\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})
URI - (@)?(href=')?(HREF=')?(HREF=\")?(href=\")?(http://)?[a-zA-Z_0-9\\-]+(\\.\\w[a-zA-Z_0-9\\-]+)+(/[#&\\n\\-=?\\+\\%/\\.\\w]+)?") && !data[i].matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$
端口号 - ^\+?\d+$
IPv4 地址 - ^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$
我的解析器方法:
public void setList(String Page){
String[] data = Page.toLowerCase().replace("#comment#", "").split(";"); //remove comments
String[] dateTime = null; //date time array
String formattedIP = null; //stores the parsed IP address
for(int i = 0; i < data.length; i++){
if(data[i].contains("/")){ //date and time field
dateTime = data[i].split(" ");
dates.add(dateTime[0].substring(dateTime[0].indexOf('/') - 4 ));
times.add(dateTime[1]);
}
formattedIP = data[i].replace(dateTime[0].substring(dateTime[0].indexOf('/') - 4 ),"").replace(dateTime[1], "").trim();
if(formattedIP.matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$")){
IPs.add(formattedIP);
}
if(data[i].matches("-?\\d+(\\.\\d+)?")){
ports.add(data[i]);
}
if(data[i].matches("(@)?(href=')?(HREF=')?(HREF=\")?(href=\")?(http://)?[a-zA-Z_0-9\\-]+(\\.\\w[a-zA-Z_0-9\\-]+)+(/[#&\\n\\-=?\\+\\%/\\.\\w]+)?") && !data[i].matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$")){
URIs.add(data[i]);
}
}
}
【问题讨论】:
-
如果你的所有模式都有效,为什么不先将它们声明为
Strings,然后通过连接所有Strings 来编译Pattern?请注意,您必须删除输入的开始/结束字符(^和$)... -
你可能想在“;”上分割你的字符串然后分别正则表达式每个部分。这似乎更容易
-
您可以只做
([^;]+);并重复您拥有的;的数量...您想用它来验证数据吗?还是直接拆开? -
当您拆分不包含“;”的字符串时,您的解析器不会中断。如果一个字符串应该有5个分号,那么拆分后检查长度==6。如果不是,则输入无效。
标签: java regex string-matching data-manipulation