2011-02-05 69 views
2

这可能看起来有些奇怪的问题,但无论如何给点;冗长perl的正则表达式

我有一个字符串,我需要寻找许多许多可能的字符出现在几种组合(所以字符类是没问题的),所以这将是做到这一点的最efficent方法是什么?

我想要么堆放到一个正则表达式:

if ($txt =~ /^(?:really |really |long | regex here)$/){} 

,或者使用一些“小”的比较,但我认为这不会是很efficent:

if ($txt =~ /^regex1$/ || $txt =~ /^regex2$/ || $txt =~ /^regex3$/) {} 

或如果比较可能嵌套几个。

我会很高兴在这个问题上的任何额外的建议和其他投入。 感谢

+3

这可能没有多大关系。为什么不试一试,看看哪个更快? – 2011-02-05 21:00:03

+0

我想我会不得不问,如果有人遇到同样的问题,他们是如何处理它的......我会在我有一些时候发布结果。 – 2011-02-05 21:13:59

+2

@Bart:它*可以*很重要。考虑很多很多的选择。如果你使用`/ a | b | c | d /`它是O(1),但是如果你使用`/ a/||/b/||/c/||/d /`,那么它是O(N)。做三个嵌套的循环,第一种方式仍然是O(1),但第二种方式已经爆炸成O(N³)。我确定知道哪一个**我**更喜欢! :) – tchrist 2011-02-06 00:12:08

回答

5

自从早在v5.9.2,Perl的编译一组N个方案类似的:

/string1|string2|string3|string4|string5|.../ 

为特里数据结构,如果是在模式的第一件事,甚至使用Aho- Corasick匹配非常快速地找到起点。

这意味着,您的n个候选项的比赛将现在在O(1)时间,而不是于O运行(ñ)时间,这:

if (/string1/ || /string2/ || /string3/ || /string4/ || /string5/ || ...) 

将在运行

所以你可以有O(1)或O(N)的表现:你的选择。

如果use re "debug"-Mre-debug,Perl会显示你的模式,这些线索结构。

0

这会不会取代一段时间的测试。如果可能的话,如果可能的话,我会建议使用o标志,这样Perl就不会在每次评估时重新编译你的(大)正则表达式。当然,这只有在这些字符组合对于每次评估都没有改变的情况下才有可能。

0

我认为这取决于你的regex多久。有时更好地划分非常长的表达式。