2

最近,我对正则表达式变得友好,并使用它们非常有效地完成了许多任务。与大多数 perl 一样,TIMTOWTDI 模糊了我的判断。有时我可以使用相等运算符或绑定运算符。但是,是否有时更适合使用其中一个?

首先是简化案例

my $name = 'Chris';
if ($name eq 'Chris') { print 'What a great name!'; }
if ($name =~/^Chris$/) { print 'Yip sure is a great name; }

所以在这种情况下,这是最简化的,使用等式减少了打字,但是在这个简化的例子中,其中一个或另一个有什么好处。

在一个稍微复杂的例子中

my $name = 'Christopher';
if ($name eq 'Chris' || $name eq 'Christopher') { print 'What a great name!'; }
if ($name =~ /^Chris(?:topher)?$/) { print 'Yip sure is a great name; }

这里的绑定操作符少打字。但是,我不确定其中一个好处是否会超过另一个。

如果您将整个字符串与固定值匹配以使用相等运算符,并且如果您将字符串与模式匹配,例如任何 5 位字符串,则一般规则也是如此,/\d{5}/则使用绑定运算符。

在上面的示例中使用绑定运算符是否不合适。我很欣赏这些例子只是虚构的,可能无法反映现实生活中的问题。然而,他们是我想试图解释我的问题的人。

4

3 回答 3

5

但是,在这个简化的示例中,其中之一是否有任何好处。

好吧,它们并不等同。/^Chris$/匹配ChrisChris后跟换行符。

如果您使用了等效的模式 ( /^Chris\z/),则不同之处在于性能。单个字符串比较将比正则表达式匹配更快。也更清楚了。

对于更复杂的比较,您通常希望使用更简单、更清晰、更易于维护的方法。解决性能问题(通过使用配置文件和运行基准测试)。

于 2013-10-28T00:54:44.563 回答
3

我希望eq运算符的性能稍微好一点(如果有的话),因为正则表达式可能需要一个编译阶段以及在做出决定之前进行分析。

所以在这种情况下:

if ($name eq 'Chris') { print 'What a great name!'; }
if ($name =~/^Chris$/) { print 'Yip sure is a great name; }

...我希望第一个语句最快。

但是,在第二个示例中,您必须考虑提供逻辑 OR 的失败案例的总时间:

if ($name eq 'Chris' || $name eq 'Christopher') { print 'What a great name!'; }
if ($name =~ /^Chris(?:topher)?$/) { print 'Yip sure is a great name; }

......这里的东西少了一些切割和干燥。当然,eq可能更快,但eq比不需要回溯的正则表达式(在本例中)快 2 秒?我不能这么肯定。

通常您不必考虑性能优势。所以你不能说一个比另一个“更好”——在这种情况下,我通常会鼓励代码清晰。但重要的是要意识到这eq是非常无情的,而正则表达式非常灵活 - 允许不区分大小写的搜索,锚定到开头等。当你遇到一些比较速度至关重要的代码时,最终你会想要基准。

于 2013-10-27T20:28:19.217 回答
1

正则表达式的强大之处在于它的可变性。
当您为正则表达式引擎提供模板时,您“建议”将结果与引擎匹配。
从本质上讲,它与 C "strncmp()" 相同,就像您在 Perl 中所做的那样,即:$str eq "asdf",两者都是模板。

但是,您不能仅用一种语言很好地描述变量,这就是存在正则表达式引擎的原因。

“eterring”引擎存在开销,即:重置变量、状态跟踪等。
但在那之后,引擎将胜过任何你能
想到的语言结构组合。不是一点点,而是一个巨大的、巨大的百分比。

于 2013-10-27T21:10:41.207 回答