Java 正则表达式:哪个更快:连续的简单表达式还是一个复杂的表达式?

3

我正在编写一个程序,需要去除相当多的垃圾信息。我使用正则表达式来实现,由于我的程序在速度方面比较敏感,我需要知道哪种解决方案更快:使用一系列连续而相对简单的正则表达式,还是使用一个相当复杂的单一正则表达式?

此致, Timofey。


9
没有实际表达方式很难判断。这个问题没有普适的答案,但你可以轻易地测试两种方法的效果。 - Tomalak
不仅仅是正则表达式;你匹配的文本也可以产生巨大的影响。 - tripleee
2个回答

4

你需要进行基准测试以确保结果,并确保博客记录下测试结果。我怀疑一个大的正则表达式比许多小的正则表达式更快,但我很想知道你的发现。

java.util.regex.Pattern类非常复杂,我不敢保证它的优化表现如何。我知道正则表达式会编译成图形,因此显而易见的是可以将重叠路径合并。你将许多变量放入单个表达式中,就会有更多这样的机会。这也可能减少对输入数据的传递次数。


1
+1 指出只有(写得好的)基准测试才能回答这个问题,而且一个人无法知道根据实现会发生什么样的优化。例如,perl 从许多替代方案中创建 trie 数据结构:例如,看看 perl -Mre=debug -cwe '/abc|adec|adfe|abcdgd|adfxe/' 如何工作。Trie 比逐个测试快得多。听起来 Java 却不够聪明。 - tchrist
确实。有些语言(和实现)比标准Java更适合于大量文本处理。这确实引出了一个问题,即开源Java正则表达式框架(如GNU regexp)是否更好。 - Barend

3

正如你们中的许多人建议的那样,我尝试了一下,并得出了以下结果:

将我使用的一些正则表达式连续加入到一个中后,我的执行时间几乎增加了一倍(从处理1000个字符串需要10秒变为处理相同数量的字符串需要18秒)。

所以,基本上可以得出结论:顺序地尽可能多地删除符号,使剩余的字符串在下一个清理的正则表达式中尽可能短,比长正则表达式更快。

PS。不幸的是,我无法张贴正则表达式本身,因为它们会被代码高亮显示器损坏。

PPS: 这里是我依次使用的一些正则表达式:

s = s.replaceAll("<span STYLE=\"color:[\w|\d|\(|\)|\,]++\">", "");
s = s.replaceAll("</{0,1}\w++>", "");
s = s.replaceAll("<img SRC=\"/gif/", "");
s = s.replaceAll("(width|height)\s{0,}=\s{0,}\"{0,1}\d{1,}\"{0,1}", "");
s = s.replaceAll("align=\"\w++\"", "");

然后我将它们结合在一起,将每个正则表达式放在括号中,并在它们之间放置|。


感谢您报告您的发现。无论如何,您能否发布您的正则表达式呢?如果您无法正确格式化,也许管理员可以帮忙。 - Barend
这也符合我的发现,即使在JDK 8中也是如此。我本来以为大的会更快,但小的似乎更快。 - Ayman

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