Tôi có thể nghĩ ra ba cách đáng tin cậy. Đầu tiên là thay thế mọi thứ sau trận đấu thứ N với chính nó.
my $max = 5;
$s =~ s/(aa)/ $max-- > 0 ? 'bb' : $1 /eg;
Điều đó không hiệu quả nếu có nhiều hơn N so khớp. Cho rằng, chúng ta cần phải di chuyển vòng lặp ra khỏi động cơ regex. Hai phương pháp tiếp theo là cách để làm điều đó.
my $max = 5;
my $out = '';
$out .= $1 . 'bb' while $max-- && $in =~ /\G(.*?)aa/gcs;
$out .= $1 if $in =~ /\G(.*)/gcs;
Và thời gian này, tại chỗ:
my $max = 5;
my $replace = 'bb';
while ($max-- && $s =~ s/\G.*?\Kaa/$replace/s) {
pos($s) = $-[0] + length($replace);
}
Bạn có thể bị cám dỗ để làm một cái gì đó giống như
my $max = 5;
$s =~ s/aa/bb/ for 1..$max;
nhưng cách tiếp cận đó sẽ thất bại cho các mẫu khác và/hoặc biểu thức thay thế.
my $max = 5;
$s =~ s/aa/ba/ for 1..$max; # XXX Turns 'aaaaaaaa'
# into 'bbbbbaaa'
# instead of 'babababa'
+1 để chỉ ra vấn đề với' s /.../ .../cho 1..N' Nhưng ví dụ có một lỗ hổng nhỏ, 'aaaa' sẽ trở thành' bbba' không 'bbbb'. – Qtax
@Qtax, Cảm ơn.Tôi không muốn downvote Hubert Schölnast vì anh ấy mới và câu trả lời của anh ấy thực sự phù hợp với câu hỏi cụ thể, nhưng tôi nghi ngờ OP thực sự làm việc với 'aa' và' bb'. Vì vậy, tôi đã giải thích tại sao giải pháp của anh ấy mỏng manh ở đây. – ikegami
@ikegami nó đã được một thời gian dài kể từ khi tôi đã thực hiện perl, nhưng nếu bạn có thể theo dõi những gì vị trí trong chuỗi bạn đang có và khởi động lại tìm kiếm regex từ đó, nó sẽ khắc phục vấn đề với 's /.../ .../cho 1..N'. Mặc dù nó sẽ là một chút xấu xí. –