我想在字符串中找到"BBB"
的所有出现,并用"D"
替换它们。例如,我有"ABBBBC"
并希望生成"ADBC"
和"ABDC"
。 (首先替换第一个BBB
,然后替换另一个BBB
)。在Perl中有一个很好的方法吗?
$str = "ABBBBC";
for ( $str =~ m/B(?=BB)/g ) {
# I match both the BBBs here, but how to substitute the relevant part?
}
我想获得这个数组:('ADBC', 'ABDC')
,它来自将BBB
更改为D
。字符串"ABBBBBC"
会给我"ADBBC"
,"ABDBC"
和"ABBDC"
。
答案 0 :(得分:4)
要获得重叠匹配,您必须使用Perl的pos
运算符。
<强>
pos SCALAR
强>
的pos
强>
返回最后m//g
次搜索为所讨论的变量停止的位置的偏移量(未指定变量时使用$_
)。请注意,0是有效的匹配偏移量。undef
表示搜索位置已重置(通常是由于匹配失败,但也可能是因为尚未在标量上运行匹配)。
pos
直接访问regexp引擎用于存储偏移量的位置,因此分配给pos将改变该偏移量,因此也将影响正则表达式中的\G
零宽度断言。这两种效果都会在下一场比赛中发生,因此您无法在当前比赛中使用pos
影响排名,例如(?{pos() = 5})
或s//pos() = 5/e
。设置
pos
也会重置匹配的零长度标记,在Repeated Patterns Matching a Zero-length Substring in perlre下描述。
例如:
#! /usr/bin/env perl
use strict;
use warnings;
my $str = "ABBBBC";
my @replaced;
while ($str =~ m/^(.*)\G(.+?)BBB(.*)$/g ) {
push @replaced, $1 . $2 . "D" . $3;
pos($str) = length($1) + 1;
}
print "[", join("][" => @replaced), "]\n";
输出:
$ ./prog [ADBC][ABDC]
答案 1 :(得分:0)
local our @replaced;
'ABBBBC' =~ /^(.*)BBB(.*)\z(?{ push @replaced, $1.'D'.$2 })(?!)/s;