【问题标题】:What java regex can I use to match this string?我可以使用什么 java 正则表达式来匹配这个字符串?
【发布时间】: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


【解决方案1】:

你为什么要匹配整行。只需将行拆分为;

String[] arr = line.split(";");

然后使用arr[0], arr[1], arr[2] 等访问/检查/解析单个数组组件。

【讨论】:

  • 拆分后他仍然需要使用一些正则表达式,但此时问题会简化很多
  • 感谢您指出这一点。我实际上就是这样做的,我需要这个特定的正则表达式的原因是为了验证它是否采用上述格式。
  • @JaminBecker 所以分别验证数组的每个元素
  • @JaminBecker:验证单个数组元素要容易得多。
  • @JaminBecker 如果其中一个无效,那么它们都是无效的。那有什么问题? boolean valid = validateDate(arr[0]) &amp;&amp; validateTime(arr[1]) &amp;&amp; ...
【解决方案2】:

每个@Cruncher @JaminBecker如果其中一个无效,那么它们都是无效的。那有什么问题?布尔有效 = validateDate(arr[0]) && 验证时间(arr[1]) && ...

因此我只是确保我从字符串中拆分出来的数组的当前索引不包含 cmets,更好的解决方案 那么下面的复杂正则表达式是我修改后的解析器方法

public void setList(String Page){
    String[] data = Page.toLowerCase().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("#")){**
            if(data[i].contains("/")){ //date and time field
                System.out.println(data[i]);
                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]);
            }
        }
    }


}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多