带有单引号查找的Java Regex Bug?

时间:2017-01-03 10:29:44

标签: java regex string

可能是我还没看到的PEBKAC,但是:(?:[^']+|'')+应该匹配带有非双引号的字符串(基于Regex: Match double single quote inside string并使用Regex 101进行测试)。

但是,如果在Java Pattern对象中使用上述内容,即Pattern noSingleQuote = Pattern.compile("(?:[^']+|'')+");,则行为如下:

  • 如果匹配的String不包含单引号,则一切正常,匹配器返回true(即noSingleQuote.matcher("tester").matches()noSingleQuote.matcher("tes''ter").matches()正常)
  • 如果匹配的String确实包含单引号,那么JDK Matcher会在内部遇到无限循环(即,noSingleQuote.matcher("tes'ter").matches()会导致无限循环)

在8u112本地测试,并在Regex Planet

在线测试

我没有深入调试无限循环发生的原因和原因。

任何想法,见解?

更新:给定的示例不会重现所描述的行为,使用"select x, y, z where x = ''t'';""select x, y, z where x = 't'';"再现我上面描述的内容。 这对我来说意味着错误(?)不仅仅是因为单引号。

Update2:它不是一个无限循环,但似乎与String本身的空格数成正比。由于我遇到的生产代码,它有一个非常长的String,有很多空格,我只是假设它是一个无限循环。 Mea culpa。

2 个答案:

答案 0 :(得分:1)

我想你已经遇到了我在Java regex to match start/end tags causes stack overflow中描述的已知问题。简而言之,原因是Java正则表达式引擎以低效的方式处理量化的替换,并且unroll这样的模式是个好主意。

在您的情况下,模式应定义为

String pattern = "[^']*(?:''[^']*)*";

这里,逻辑是线性并且更少地发送回溯

  • [^']* - 除'
  • 以外的零个或多个字符
  • (?:''[^']*)* - 零个或多个序列:
    • '' - 双单引号
    • [^']* - 除'以外的零个或多个字符。

答案 1 :(得分:0)

我认为你的无限循环在其他地方。

<!--
         Blur Layout start
      -->
    <declare-styleable name="BlurLayout">
        <attr name="downscaleFactor" format="float" />
        <attr name="blurRadius" format="integer" />
        <attr name="fps" format="integer" />
    </declare-styleable>

    <!--
       Blur Layout end
    -->

工作正常,没有问题。

JDK-1.8.0_111