【问题标题】:What is the downside of scanning with regular expressions in Java在 Java 中使用正则表达式进行扫描有什么缺点
【发布时间】:2016-11-20 21:18:06
【问题描述】:

我知道除了扫描预定义的primitive 类型之外,我还可以扫描自己的用户定义模式,这在扫描更复杂的数据时很有帮助。我说的是Scanner.next(String pattern) 方法。 但是,在我读到的关于 Java 的书中,有一段说

“使用正则表达式扫描时有一个警告。 模式仅与下一个输入标记匹配,因此如果您的 模式包含一个永远不会匹配的分隔符。”

我真的不明白这是什么意思,以及这种扫描在哪些情况下不适用

【问题讨论】:

  • 你指的是什么书? SO 不是任意未引用垃圾的验证站点。
  • 用 Java 思考,第 4 版 - Bruce Eckel

标签: java regex java.util.scanner


【解决方案1】:

假设您有一个逗号, 作为分隔符。现在不知何故(也许它是由其他人提供的)你想出了一个模式ab,cd。由于模式包含分隔符,扫描器将尝试将ab,cd 先匹配到ab,然后再匹配到cd,导致不匹配。

请注意,这是一个警告,不一定是您很容易遇到的事情。

【讨论】:

  • 你能解释一下你的例子中的分隔符和模式是如何使用的吗?我认为模式将被扫描仪用作分隔符。这怎么可能是两种不同的东西?
  • @Codebender 就像nextInt() 将扫描一个整数(以\n 作为分隔符以及其他任何默认分隔符),next(String pattern) 将扫描与模式匹配的下一个输入.首先根据分隔符对输入进行标记化,然后进行匹配,无论是正则表达式模式、整数、行等。
  • 非常感谢。我刚刚注意到存在 next(pattern) 方法。我正在考虑使用 useDelimiter(pattern) 的模式作为分隔符。
【解决方案2】:

说说《Thinking in Java》一书中给出的原始例子,这个程序:

String threatData =
        "58.27.82.161@02/10/2005\n" +
        "204.45.234.40@02/11/2005\n" +
        "58.27.82.161@02/11/2005\n" +
        "58.27.82.161@02/12/2005\n" +
        "58.27.82.161@02/12/2005\n" +
        "[Next log section with different data format]";

Scanner sc = new Scanner(threatData);
Pattern pattern = Pattern.compile("(\\d+([.]\\d+){3})@" + "(\\d{2}/\\d{2}/\\d{4})");
                                             ///     ^
while(sc.hasNext(pattern)) {
    System.out.println(sc.next(pattern));  
    MatchResult matchResult = sc.match();
    System.out.println("Threat from " + matchResult.group(1) + " on " + matchResult.group(3));
}

正确打印所需的输出。 但是, 当您通过将 threatData 中的 @ 替换为空格 ' 'pattern 中的 @ 替换为 @ 对其进行轻微更改时987654325@,您将观察到扫描仪无法匹配该模式,因为它包含默认分隔符。

String threatData =
        "58.27.82.161 02/10/2005\n" +
        "204.45.234.40 02/11/2005\n" +
        "58.27.82.161 02/11/2005\n" +
        "58.27.82.161 02/12/2005\n" +
        "58.27.82.161 02/12/2005\n" +
        "[Next log section with different data format]";

Scanner sc = new Scanner(threatData);
Pattern pattern = Pattern.compile("(\\d+([.]\\d+){3})\\s" + "(\\d{2}/\\d{2}/\\d{4})");
                                                //    ^^

【讨论】:

    猜你喜欢
    • 2016-01-23
    • 2015-06-26
    • 2014-10-18
    • 2021-05-20
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多