是否可以指定要替换的最大匹配数。例如,如果在“Hello World”中匹配“l”,是否可以替换前2个l'字符,而不是第3个字符而不循环?
答案 0 :(得分:9)
这是一种方法。这需要使用(?{code})
构造内的(?(condition)true-sub-expression|false-sub-expression)
块在RE内更新外部计数器。有关说明,请参阅perldoc perlre。
use Modern::Perl;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
my $count = 2;
my $re = qr/
(l)
(?(?{$count--})|(*FAIL))
/x;
say "Looking for $count instances of 'l' in $string.";
my ( @found ) = $string =~ m/$re/g;
say "Found ", scalar @found, " instances of 'l': @found";
输出结果为:
Looking for 2 instances of 'l' in Hello world!
Found 2 instances of 'l': l l
这是对同一个正则表达式的另一个测试,但这次我们跟踪匹配的位置只是为了证明它匹配前两次出现。
use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
my $count = 2;
my $position = 0;
my $re = qr/
(l)(?{$position=pos})
(?(?{$count--})|(*FAIL))
/x;
while( $string =~ m/$re/g ) {
say "Found $1 at ", $position;
}
这次输出是:
Found l at 3
Found l at 4
我认为我不会推荐任何此类内容。如果我正在考虑将匹配仅限制为字符串的一部分,我将匹配字符串的substr()
。但如果你喜欢生活在边缘,请继续玩这个片段吧。
这是替代:
use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
say "Before substitution $string";
my $count = 2;
my $re = qr/
(l)
(?(?{$count--})|(*FAIL))
/x;
$string =~ s/$re/L/g;
say "After substitution $string";
输出:
Before substitution Hello world!
After substitution HeLLo world!
答案 1 :(得分:9)
$str = "Hello world!";
$str =~ s/l/r/ for (1,2);
print $str;
我不知道循环有什么坏处。
实际上,这是一种方式:
$str="Hello world!";
$str =~ s/l/$i++ >= 2 ? "l": "r"/eg;
print $str;
这是一个循环,各种各样,因为当你这样做时,// /// g以循环方式工作。但不是传统的循环。
答案 2 :(得分:0)
简答:不。您需要在某种循环中执行替换。