为什么Java正则表达式“匹配”与“查找”在使用非贪婪模式时获得不同的匹配?

所以我遇到了一个错误,因为期望match()方法找到与使用find()完全相同的匹配。 通常情况就是如此,但看起来如果非贪婪的模式可以被拉伸到贪婪地接受整个字符串,那么它是允许的。 这似乎是Java中的一个错误。 我错了吗? 我没有在文档中看到任何表明此行为的内容。

Pattern stringPattern = Pattern.compile("'.*?'"); String nonSingleString = "'START'===stageType?'active':''"; Matcher m1 = stringPattern.matcher(nonSingleString); boolean matchesCompleteString = m1.matches(); System.out.println("Matches complete string? " + matchesCompleteString); System.out.println("What was the match? " + m1.group()); //group() gets the string that matched Matcher m2 = stringPattern.matcher(nonSingleString); boolean foundMatch = m2.find(); //this looks for the next match System.out.println("Found a match in at least part of the string? " + foundMatch); System.out.println("What was the match? " + m2.group()); 

输出

匹配完整的字符串? 真正
比赛是什么? ‘START’ === stageType ‘主动’: ”
在至少部分字符串中找到匹配项? 真正
比赛是什么? ‘开始’

这很有道理。

matches(...)方法必须尝试使用​​整个字符串,因此即使使用非贪婪模式也是如此。

find(...)方法可能会找到一个子字符串,因此如果找到任何匹配的子字符串,它会在该点处停止。

他们应该是不同的。 Matcher#matches尝试匹配完整的输入字符串使用隐式锚点^$围绕你的正则表达式,而Matcher#find #find匹配wahtever你的正则表达式可以匹配。

根据Javadoc :

public boolean matches()

尝试将整个区域与模式匹配。 如果匹配成功,则可以通过start,end和group方法获得更多信息。

public boolean find()

尝试查找与模式匹配的输入序列的下一个子序列。