Java正则表达式实现中的错误?

Asa*_*aph 27 java regex

我在Java的正则表达式实现中发现了一些意想不到的行为.使用java.util.regex.Pattern和时,使用Matcher 方法时java.util.regex.Matcher,以下正则表达式在输入上无法正确"Merlot"匹配find():

((?:White )?Zinfandel|Merlot)
Run Code Online (Sandbox Code Playgroud)

如果我更改最外部匹配组中表达式的顺序,Matcher的find()方法确实匹配.

(Merlot|(?:White )?Zinfandel)
Run Code Online (Sandbox Code Playgroud)

这是一些说明问题的测试代码.

RegexTest.java

import java.util.regex.*;

public class RegexTest {
    public static void main(String[] args) {
        Pattern pattern1 = Pattern.compile("((?:White )?Zinfandel|Merlot)");
        Matcher matcher1 = pattern1.matcher("Merlot");
        // prints "No Match :("
        if (matcher1.find()) {
            System.out.println(matcher1.group(0));
        } else {
            System.out.println("No match :(");
        }

        Pattern pattern2 = Pattern.compile("(Merlot|(?:White )?Zinfandel)");
        Matcher matcher2 = pattern2.matcher("Merlot");
        // prints "Merlot"
        if (matcher2.find()) {
            System.out.println(matcher2.group(0));
        } else {
            System.out.println("No match :(");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

预期的产出是:

Merlot
Merlot
Run Code Online (Sandbox Code Playgroud)

但实际输出是:

No Match :(
Merlot
Run Code Online (Sandbox Code Playgroud)

我已经验证了在Ubuntu linux上的Java版本1.7.0_11以及OSX 10.8.2上的Java版本1.6.0_37中存在这种意外行为.我昨天向甲骨文报告了这种行为的错误,并收到了一封自动发送的电子邮件告诉我我的错误报告已经收到并且内部审核ID为2441589.当我在他们的bug中搜索该ID时,我找不到我的错误报告数据库.(你能听到蟋蟀吗?)

我是否发现了Java中可能经过彻底测试和使用的正则表达式实现的错误(很难相信2013年),或者我做错了什么?

Mik*_*rov 8

下列:

import java.util.regex.*;

public class T {
  public static void main( String args[] ) {
    System.out.println( Pattern.compile("(a)?bb|c").matcher("c").find() );
    System.out.println( Pattern.compile("(a)?b|c").matcher("c").find() );
  }
}
Run Code Online (Sandbox Code Playgroud)

版画

false
true
Run Code Online (Sandbox Code Playgroud)

上:

  • JDK 1.7.0_13
  • JDK 1.6.0_24

下列:

import java.util.regex.*;

public class T {
  public static void main( String args[] ) {
    System.out.println( Pattern.compile("((a)?bb)|c").matcher("c").find() );
    System.out.println( Pattern.compile("((a)?b)|c").matcher("c").find() );
  }
}
Run Code Online (Sandbox Code Playgroud)

打印:

true
true
Run Code Online (Sandbox Code Playgroud)


som*_*ytt 4

它似乎在 Java 1.8 中得到修复。

Welcome to Scala version 2.11.0-20130930-063927-2bba779702 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0-ea).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import java.util.regex._
import java.util.regex._

scala> Pattern.compile("((?:White )?Zinfandel|Merlot)")
res0: java.util.regex.Pattern = ((?:White )?Zinfandel|Merlot)

scala> .matcher("Merlot")
res1: java.util.regex.Matcher = java.util.regex.Matcher[pattern=((?:White )?Zinfandel|Merlot) region=0,6 lastmatch=]

scala> .find()
res2: Boolean = true
Run Code Online (Sandbox Code Playgroud)