Java中Matcher.find()方法的实际行为究竟是什么?
java.util.regex.Matcher.find()的JavaDoc描述与实际行为的差异
java.util.regex.Matcher.find()的JavaDoc描述如下:
尝试查找输入序列中与模式匹配的下一个子序列。
此方法从匹配器区域的开头开始,或者如果之前调用此方法成功且匹配器未被重置,则从之前匹配未覆盖的第一个字符开始。
如果匹配成功,则可以通过start、end和group方法获取更多信息。
但上述描述并不符合该方法的实际行为。经过测试,我对其实际行为有了直观认知,但不确定该行为是否有明确的文档说明。
示例1:分支模式的匹配顺序影响结果
Pattern.compile("a|ad").matcher("ad").find() --> group() = "a" Pattern.compile("ad|a").matcher("ad").find() --> group() = "ad"
显然,子序列a同时匹配这两个模式,但第二个匹配器跳过了a,将ad作为“与模式匹配的下一个子序列”返回。
示例2:贪婪量词的匹配行为
Pattern.compile("[abc]+").matcher("ababab").find() --> group = "ababab"
我们都知道[abc]+可以匹配单个a、b或c,但实际调用find()时,它跳过了单个a的匹配情况,直接匹配了整个字符串。
我认为实际行为的本质是,方法的实现依赖于模式的构造逻辑,会按特定顺序尝试模式的各个部分。比如a|ad会优先匹配a并忽略后续的d,而ad|a则优先匹配更长的ad;[abc]+作为贪婪量词,即使在查找“下一个子序列”时也会尽可能匹配最长的符合条件的序列。
现在的问题是,该如何修正JavaDoc的描述?它既不是匹配最长子序列(从a和ad的对比中可见),也不是匹配第一个出现的子序列(从ababab和单个a的对比中可见)。那么这个方法的实际逻辑到底是什么?能否给出一个合理的规范性定义?
需要强调的是:我理解背后的实现原理,只是想指出该方法的行为与现有JavaDoc不符,并且不清楚如何在不直接描述实现细节的前提下修正JavaDoc。find()并非查找“与模式匹配的下一个子序列”,而是基于模式的构造方式,查找某一个符合模式的下一个子序列。
内容的提问来源于stack exchange,提问作者Todd O'Bryan

