使用交替或字符类进行单字符匹配?

Mar*_* Ba 11 regex perl

(注意:标题似乎并不清楚 - 如果有人可以改写,我就是全部!)

鉴于这个正则表达式:(.*_e\.txt),它匹配一些文件名,我需要添加一些其他单字符后缀除了e.我应该选择一个角色类还是应该使用替换?(或者这真的很重要??)

也就是说,以下哪两个似乎"更好",以及为什么:

a)(.*(e|f|x)\.txt),或

b) (.*[efx]\.txt)

Tim*_*ker 23

使用[efx]- 这正是设计用于的字符类:匹配其中一个包含的字符.因此,它也是最可读和最短的解决方案.

我不知道它是否更快,但如果不是,我会非常惊讶.它肯定不会慢.

我的推理(没有编写正则表达式引擎,所以这是纯粹的猜想):

正则表达式令牌[abc]将在正则表达式引擎的一个步骤可应用于:"是下一个字符中的一个a,b或者c?"

(a|b|c) 然而告诉正则表达式引擎

  • 如有必要,请记住字符串中用于回溯的当前位置
  • 检查是否可以匹配a.如果是这样,成功.如果不:
  • 检查是否可以匹配b.如果是这样,成功.如果不:
  • 检查是否可以匹配c.如果是这样,成功.如果不:
  • 放弃.


Tot*_*oto 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;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

结果:

              Rate alternation       class
alternation 2855/s          --        -50%
class       5677/s         99%          --
Run Code Online (Sandbox Code Playgroud)

  • 这是一个有趣的 - 而且,我认为,有用 - 插图.虽然有很多东西没有进入.如果您改变输入数据,您将获得不同的性能,如果您改变模式,也将获得不同的性能.例如,`[bcdfghjklmnñpqrstvwxz]`vs`(b | c | d | f | g | h | j | k | l | m | n |ñ| p | q | r | s | t | v | w | x | z)`西班牙辅音的时间长得多,可能应该表现出不同的性能特征. (2认同)