Perl:字符串索引函数或正则表达式 - 哪个更好,什么时候?

Dea*_*man 8 regex perl

我正在写一些Perl脚本,我需要做很多字符串匹配.例如:

my $str1 = "this is a test string";
my $str2 = "test";
Run Code Online (Sandbox Code Playgroud)

要查看$ str1是否包含$ str2 - 我发现有两种方法:

方法1:使用索引功能:

if ( index($str1, $str2) != -1 ) { .... }
Run Code Online (Sandbox Code Playgroud)

方法2:使用正则表达式:

if( $str1 =~ /$str2/ ) { .... }
Run Code Online (Sandbox Code Playgroud)

哪个更好?什么时候我们应该使用其中的每一个?

Tot*_*oto 6

以下是Benchmark的结果:

use Benchmark qw(:all) ;
my $count = -1;
my $str1 = "this is a test string";
my $str2 = "test";
my $str3 = qr/test/;

cmpthese($count, {
    'type1' => sub { if ( index($str1, $str2) != -1 ) { 1 } },
    'type2' => sub { if( $str1 =~ $str3 ) { 1 } },
});
Run Code Online (Sandbox Code Playgroud)

结果(匹配发生时):

           Rate type2 type1
type2 1747627/s    --  -70%
type1 5770465/s  230%    --
Run Code Online (Sandbox Code Playgroud)

为了得出结论,测试匹配:

my $str2 = "text";
my $str3 = qr/text/;
Run Code Online (Sandbox Code Playgroud)

结果(未匹配时):

           Rate type2 type1
type2 1857295/s    --  -67%
type1 5560630/s  199%    --
Run Code Online (Sandbox Code Playgroud)

结论:

index函数比正则表达式匹配快得多.


pts*_*pts 0

如果需要子字符串匹配,请使用index. 如果您需要正则表达式匹配(对于正则表达式元字符具有特殊含义),请使用=~. 子字符串匹配通常更快,但 Perl 中的正则表达式经过了很好的优化,简单的正则表达式匹配速度快得惊人。为自己进行基准测试。

从 Perl 5.6 开始,Perl 足够聪明,可以重新编译$str =~ /$str2/iff中的 regexp$str2自上次编译以来已更改。要完全控制正则表达式的编译时间,请使用qr/$str2/. 请参阅Perl 正则表达式的“o”修饰符是否仍然提供任何好处?for q/.../o(已过时)和qr/.../(大多数时候不需要,但可能有用)。

  • 如果 `$str2` 没有改变,模式将不会被重新编译,所以 `/o` 是没有用的。如果`$str2`确实改变了,那么模式需要重新编译,所以`/o`是错误的。`/o` 充其量是无用的,所以不,不要使用 `/o`! (7认同)
  • 我想强调的是@ikegami [所说](http://stackoverflow.com/questions/30744379/perl-string-index-function-or-regex-which-is-better-and-when#comment49545977_30744417)适用,不仅在这种情况下,而且几乎在所有情况下。有关更多信息,请参阅[此问题](http://stackoverflow.com/q/550258/20938)。 (3认同)