Java正则表达式性能:勉强量词还是字符类?

5

这两种方法哪个更高效,或者(如果等效)哪一种更易读?我正在尝试匹配括号内的所有内容。

Pattern p1 = Pattern.compile("\\([^)]*\\)");
Pattern p2 = Pattern.compile("\\(.*?\\)");

对我来说,第二个读起来更好,但使用了可能会引起困惑的勉强量词,我不确定这是否会导致性能损失。
编辑
不要错过显示这个更好的答案:
Pattern p3 = Pattern.compile("\\([^)]*+\\)");
2个回答

5
\([^)]*\)会更快,尽管如果输入较小时可能不会注意到。当您使[^)]*具有所有权时,更好的收益可能会发生:[^)]*+。这样,正则表达式引擎将不会跟踪[^)]*匹配的所有字符,以防需要回溯(在[^)]*\)的情况下不会发生回溯)。使模式具有所有权会导致正则表达式引擎记住此模式已匹配的字符。

同样,这可能不会引起注意,但如果您的输入变得更大,则*我非常确定.*?[^)]*之间的差异小于[^)]*[^)]*+之间的差异。

*运行一些基准测试以确保!


3
这个相比于“p2”的非贪婪方式,性能更好,因为后者会导致回溯。
Pattern p1 = Pattern.compile("\\([^)]*\\)");

看看这篇文章

在链接的文章中,@BartKiers描述了它为“使用惰性量词,使引擎在每个字符之后向前回溯”,这对我来说有些意义。 - Cory Kendall
@CoryKendall,啊,我没看文章。根据“非贪婪方式,会导致回溯”的措辞,我以为他的意思是贪婪方式不会导致回溯。现在我明白了xdazz(和文章作者)的意思。谢谢! - Bart Kiers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接