Java 当一个或正则表达式组的两半匹配时,是否定义将选择哪一个?
我运行了以下代码:Java 当一个或正则表达式组的两半匹配时,是否定义将选择哪一个?,java,regex,Java,Regex,我运行了以下代码: public static void main(String[] args) { Pattern pattern = Pattern.compile("(asd|asdf).*"); Pattern pattern2 = Pattern.compile("(asdf|asd).*"); Matcher m = pattern.matcher("asdf"); Matcher m2 = pattern2.matcher("asdf");
public static void main(String[] args) {
Pattern pattern = Pattern.compile("(asd|asdf).*");
Pattern pattern2 = Pattern.compile("(asdf|asd).*");
Matcher m = pattern.matcher("asdf");
Matcher m2 = pattern2.matcher("asdf");
if (m.matches()) {
System.out.println(m.group(1));
}
if (m2.matches()) {
System.out.println(m2.group(1));
}
}
我得到以下输出:
自闭症
asdf
似乎在双方都匹配的情况下,选择了OR组的左侧。然而,我还没有找到这种行为的记录。有人知道是否定义了行为吗?在非POSIX正则表达式风格(如Java、as)中,第一个选项是匹配的。在POSIX中,匹配最长的备选方案 请参见关于替换的说明: 为了匹配
dog
或cat
,我们形成了regexpdog | cat
。与前面一样,Perl将尝试在字符串中尽可能早的点匹配regexp。在每个字符位置,Perl将首先尝试匹配第一个备选字符,dog
。如果dog
不匹配,Perl将尝试下一种替代方法,cat
。如果cat
也不匹配,则匹配失败,Perl移动到字符串中的下一个位置
请参阅描述符合NFA的替代行为的:
备选方案的顺序很重要。假设您希望使用正则表达式来匹配编程语言中的函数名列表:Get
、GetValue
、Set
或SetValue
。显而易见的解决方案是Get | GetValue | Set | SetValue
正则表达式引擎从正则表达式中的第一个标记开始,G
,从字符串中的第一个字符开始,S
。比赛失败了。然而,正则表达式引擎在启动之前研究了整个正则表达式。所以它知道这个正则表达式使用交替,并且整个正则表达式还没有失败。因此它继续使用第二个选项,即正则表达式中的第二个G
。比赛又失败了。下一个标记是正则表达式中的第一个S
。匹配成功,引擎继续使用字符串中的下一个字符以及正则表达式中的下一个标记。正则表达式中的下一个标记是刚刚成功匹配的S
之后的e
e
匹配e
。下一个标记t
与t
匹配
此时,备选方案中的第三个选项已成功匹配。因为正则表达式引擎非常急切,它认为只要选择了一个选项,整个替换就已经成功匹配。在本例中,在交替之外的正则表达式中没有其他标记,因此整个正则表达式已成功地匹配了SetValue
中的Set
然后:
但是POSIX标准确实要求返回最长的匹配,即使使用了正则表达式导向的引擎。这样的引擎不可能是急切的。即使在找到匹配项后,它也必须继续尝试所有备选方案,以便找到最长的一个
然而,如果严格定义了任何一方的上下文,那么备选方案的顺序可能是不相关的。如果您使用锚定(
^(asd | asdf)$
)来匹配完整字符串,您将只得到与正确的备选方案相对应的锚定。您是否有定义锚定的详细信息?ThanksI无法链接到任何源,但由于正则表达式试图尽可能少地匹配,我认为这一观察结果是适用的。如果你说“先”而不是“左”,这就更有意义了。不是反驳这一说法,但你有这一说法的来源吗?@ohaal。滚动到POSIX需要最长的匹配。*匹配任何字符(除换行符外)量词:*在零次和无限次之间,尽可能多地返回needed@Tushar当前位置我正在将此添加到答案中。谢谢,这是一个有用的链接。在java的文档中看到一些东西说这就是他们的实现的行为方式,这将是令人放心的!