Java正则表达式交替运算符“ |”行为似乎破了
试图为罗马数字编写正则表达式匹配器。在sed中(我认为它被认为是正则表达式的“标准”),如果你有多个由交替运算符分隔的选项,它将匹配最长的。即,
"I|II|III|IV"
将匹配“IV”代表“IV”而“III”代表“III”代表
在Java中,相同的模式匹配“I”代表“IV”而“I”代表“III”。从左到右,交替匹配之间的Java选择;也就是说,因为“I”出现在正则表达式中的“III”之前,所以它匹配。如果我将正则表达式更改为"IV|III|II|I"
,则行为会得到纠正,但这显然不是一般的解决方案。
有没有办法让Java从一个交替组中选择最长的匹配,而不是选择“第一个”?
为清晰起见,代码示例:
public static void main(String[] args)
{
Pattern p = Pattern.compile("six|sixty");
Matcher m = p.matcher("The year was nineteen sixty five.");
if (m.find())
{
System.out.println(m.group());
}
else
{
System.out.println("wtf?");
}
}
这输出"six"
没有找到相关结果
已邀请:
2 个回复
蜂佬渺
)或单词边界(
)。
编辑:我应该提一下,虽然grep,sed,awk和其他传统上使用文本导向(或DFA)引擎,你也可以找到一些使用NFA引擎的版本,甚至是两者的混合版本。
久坡
请参阅http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html上的“贪婪量词”部分。 编辑:为了回应你的评论,我认为一般的问题是你在使用不正确时继续使用轮换。在你的新例子中,你试图匹配“六”或“六十”;使用的正确模式是
,而不是
。通常,如果您有一个交替组的两个成员,使得一个是另一个的前缀,您应该重写正则表达式以消除它。否则,你不能真的抱怨引擎做错了,因为交替的语义没有说出最长的匹配。 编辑2:你的问题的字面答案是否定的,它不能被强制(我的评论是你不应该需要这种行为)。 编辑3:更多地考虑这个主题,我想到一个交替模式,其中一个字符串是另一个字符串的前缀,这是另一个原因;也就是说,除非构建底层自动机以考虑前缀,否则速度会慢一些(鉴于Java选择模式中的第一个匹配,我猜这不是这种情况)。