Puedo pensar en tres maneras confiables. El primero es reemplazar todo después del N ° partido consigo mismo.
my $max = 5;
$s =~ s/(aa)/ $max-- > 0 ? 'bb' : $1 /eg;
Eso no es muy eficiente si hay mucho más que N coincidencias. Para eso, necesitamos mover el bucle del motor de expresiones regulares. Los siguientes dos métodos son formas de hacerlo.
my $max = 5;
my $out = '';
$out .= $1 . 'bb' while $max-- && $in =~ /\G(.*?)aa/gcs;
$out .= $1 if $in =~ /\G(.*)/gcs;
Y esta vez, en el lugar:
my $max = 5;
my $replace = 'bb';
while ($max-- && $s =~ s/\G.*?\Kaa/$replace/s) {
pos($s) = $-[0] + length($replace);
}
Usted puede verse tentado a hacer algo como
my $max = 5;
$s =~ s/aa/bb/ for 1..$max;
pero tal método no es efectivo para otros modelos y/o expresiones de reemplazo.
my $max = 5;
$s =~ s/aa/ba/ for 1..$max; # XXX Turns 'aaaaaaaa'
# into 'bbbbbaaa'
# instead of 'babababa'
+1 para señalar el problema con' s /.../ .../para 1..N'. Pero el ejemplo tiene un defecto menor, 'aaaa' se convertiría en' bbba' no 'bbbb'. – Qtax
@Qtax, Gracias.No quería rechazar a Hubert Schölnast ya que es nuevo y su respuesta realmente funciona para la pregunta específica, pero dudo que OP esté trabajando realmente con 'aa' y' bb'. Así que cubrí por qué su solución es frágil aquí. – ikegami
@ikegami Ha pasado mucho tiempo desde que hice Perl, pero si pudieras hacer un seguimiento de la posición en la cadena que eres y reiniciar la búsqueda de expresiones regulares desde allí, se solucionaría el problema con 's /.../ .../para 1..N'. Aunque sería un poco feo –