Ich kann mir drei zuverlässige Möglichkeiten vorstellen. Die erste besteht darin, alles nach dem N-ten Match durch sich selbst zu ersetzen.
my $max = 5;
$s =~ s/(aa)/ $max-- > 0 ? 'bb' : $1 /eg;
Das ist nicht sehr effizient, wenn es weit mehr als N Übereinstimmungen gibt. Dazu müssen wir die Schleife aus der Regex-Engine entfernen. Die nächsten beiden Methoden sind Möglichkeiten, dies zu tun.
my $max = 5;
my $out = '';
$out .= $1 . 'bb' while $max-- && $in =~ /\G(.*?)aa/gcs;
$out .= $1 if $in =~ /\G(.*)/gcs;
Und dieses Mal in-place:
my $max = 5;
my $replace = 'bb';
while ($max-- && $s =~ s/\G.*?\Kaa/$replace/s) {
pos($s) = $-[0] + length($replace);
}
Sie könnten für andere Muster so etwas wie
my $max = 5;
$s =~ s/aa/bb/ for 1..$max;
aber dieser Ansatz wird nicht zu tun versucht sein, und/oder Ersatzausdrücke.
my $max = 5;
$s =~ s/aa/ba/ for 1..$max; # XXX Turns 'aaaaaaaa'
# into 'bbbbbaaa'
# instead of 'babababa'
+1 für das Problem mit' s /.../ .../für 1..N. Aber das Beispiel hat einen kleinen Fehler, "aaaa" würde "bbba" und nicht "bbbb" werden. – Qtax
@Qtax, Thanks.Ich wollte Hubert Schölnast nicht ablehnen, da er neu ist und seine Antwort funktioniert tatsächlich für die spezifische Frage, aber ich bezweifle, dass das OP wirklich mit 'aa' und' bb' arbeitet. Also habe ich geklärt, warum seine Lösung hier fragil ist. – ikegami
@ikegami Es ist eine lange Zeit her, seit ich Perl gemacht habe, aber wenn Sie verfolgen könnten, welche Position in der Zeichenfolge Sie sind und starten Sie die Regex-Suche von dort aus, würde es das Problem beheben mit 's /.../ .../für 1..N'. Obwohl es ein bisschen hässlich wäre. –