我有Perl代码:
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
我想用空格替换每个+
,用dog
替换cat
。
我有这个正则表达式:
$s =~ s/\+(.*)dog/ ${1}cat/g;
但是,它仅匹配第一次出现+
和最后dog
。
答案 0 :(得分:8)
两个正则表达式可能会让您的生活更轻松:
$s =~ s/\+/ /g;
$s =~ s/dog/cat/g;
以下匹配“+”,后跟一堆东西,后跟“狗”。另外,“+”在技术上是一个元字符。
/+(.*)dog/
答案 1 :(得分:6)
您可以使用'e'修饰符在s///
表达式的第二部分执行代码。
$s =~ s/(\+)|(dog)/$1 ? ' ' : 'cat'/eg;
如果$1
为真,则表示\+
匹配,因此它会替换空格;否则它代替“猫”。
答案 2 :(得分:4)
简单回答 - 使用2行!:
$s =~ s/+/ /g;
$s =~ s/dog/cat/g;
它可能在一行中进行'非贪婪'匹配,但这应该可以解决这个问题
答案 3 :(得分:4)
哈希可以做你想做的事:
#!/usr/bin/perl
use strict;
use warnings;
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my %replace = (
"+" => " ",
dog => "cat",
);
$s =~ s/([+]|dog)/$replace{$1}/g;
print "$s\n";
在评论中我看到你关注性能,这两个正则表达式解决方案更具性能。这是因为任何适用于一个正则表达式的解决方案都需要使用捕获(这会降低正则表达式)。
以下是基准测试的结果:
eval: The quick brown fox jumps over the lazy cat that is my cat
hash: The quick brown fox jumps over the lazy cat that is my cat
two: The quick brown fox jumps over the lazy cat that is my cat
Rate hash eval two
hash 33184/s -- -29% -80%
eval 46419/s 40% -- -72%
two 165414/s 398% 256% --
我使用了以下基准:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my %replace = (
"+" => " ",
dog => "cat",
);
my %subs = (
hash => sub {
(my $t = $s) =~ s/([+]|dog)/$replace{$1}/g;
return $t;
},
two => sub {
(my $t = $s) =~ s/[+]/ /g;
$t =~ s/dog/cat/g;
return $t;
},
eval => sub {
(my $t = $s) =~ s/(\+)|(dog)/$1 ? ' ' : 'cat'/eg;
return $t;
},
);
for my $k (sort keys %subs) {
print "$k: ", $subs{$k}(), "\n";
}
Benchmark::cmpthese -1, \%subs;
答案 4 :(得分:4)
Perl 5.14和更新版本能够使用非破坏性赋值链接替换,因此您可以一举杀死3只鸟:执行两次全局替换并将结果分配给新变量而不修改原始变量。
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my $result = $s =~ s/+/ /gr
=~ s/dog/cat/gr;
将+
替换为空格,并将每个dog
替换为cat
,并将结果分配到新变量中。在单行中。
答案 5 :(得分:1)
如果速度很重要,你应该坚持使用两条线。但是,当我需要一次做多个子站时,我通常更关心方便性,所以我使用像Chas建议的哈希。欧文斯。与双线程相比,两个优点是易于修改,并且表现得像预期的那样(例如,同时将“cat”替换为“dog”而将“dog”替换为“cat”)。
但是,我非常懒于手工编写正则表达式,而更喜欢用join来组装它,并使用map来逃避:
#!/usr/bin/perl
use strict;
use warnings;
my $s = "The+quick+brown+fox+jumps+over+the+lazy+dog+that+is+my+dog";
my %replace = (
"+" => " ",
dog => "cat",
);
my $regex = join "|",
#use quotemeta to escape special characters
map { quotemeta }
#reverse sort the keys because "ab" =~ /(a|ab)/ returns "a"
sort { $b cmp $a } keys %replace;
#compiling the regex before using it prevents
#you from having to recompile it each time
$regex = qr/$regex/;
$s =~ s/($regex)/$replace{$1}/g;
print "$s\n";
答案 6 :(得分:0)
我知道这是一个老话题,但是这里是Perls早于v5.14的单行代码:
127.0.0.1:3306