(注意:标题似乎并不清楚 - 如果有人可以改写,我就是全部用它!)
鉴于这个正则表达式:(.*_e\.txt)
,它匹配一些文件名,除了e
之外,我还需要添加一些其他单字符后缀。我应该选择一个角色类还是应该使用替换? (或者这真的很重要吗?)
也就是说,以下哪两个似乎“更好”,为什么:
a)(.*(e|f|x)\.txt)
或
b)(.*[efx]\.txt)
答案 0 :(得分:22)
使用[efx]
- 这正是设计用于的字符类:匹配其中一个包含的字符。因此,它也是最易读和最短的解决方案。
我不知道它是否更快,但如果不是,我会非常惊讶。它绝对不会慢。
我的推理(没有编写过正则表达式引擎,所以这是纯粹的猜想):
正则表达式令牌[abc]
将在正则表达式引擎的一个步骤中应用:“下一个字符是a
,b
还是c
?”
(a|b|c)
告诉正则表达式引擎
a
。如果是这样,成功。如果不是:b
。如果是这样,成功。如果不是:c
。如果是这样,成功。如果不是:答案 1 :(得分:13)
这是一个基准:
根据tchrist评论更新,差异更显着
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;
use Benchmark qw(:all);
my @l;
foreach(qw/b c d f g h j k l m n ñ p q r s t v w x z B C D F G H J K L M N ñ P Q R S T V W X Z/) {
push @l, "abc$_.txt";
}
my $re1 = qr/^(.*(b|c|d|f|g|h|j|k|l|m|n|ñ|p|q|r|s|t|v|w|x|z)\.txt)$/;
my $re2 = qr/^(.*[bcdfghjklmnñpqrstvwxz]\.txt)$/;
my $cpt;
my $count = -3;
my $r = cmpthese($count, {
'alternation' => sub {
for(@l) {
$cpt++ if $_ =~ $re1;
}
},
'class' => sub {
for(@l) {
$cpt++ if $_ =~ $re2;
}
}
});
<强>结果:强>
Rate alternation class
alternation 2855/s -- -50%
class 5677/s 99% --
答案 2 :(得分:1)
对于一个角色,它将具有如此微小的差异,这无关紧要。 (除非你做了很多操作)
但是,为了便于阅读(并略微提高性能),您应该使用字符类方法。
有关更多信息 - 打开圆括号(
会导致Perl开始回溯当前位置,因为您没有进一步的匹配,所以您真的不需要正则表达式。字符类不会这样做。