Perl es uno de los lenguajes donde las expresiones regulares están integradas a un nivel profundo. El principal operador de reemplazo es s///, que permite buscar y reemplazar fragmentos de cadenas según un patrón. En esta construcción hay muchos matices, especialmente al trabajar con plantillas codiciosas/perezosas, procesamiento de múltiples líneas y opciones de reemplazo.
El operador s/// ha estado presente en Perl desde las primeras versiones, y es Perl el que sentó las bases de la sintaxis de las expresiones regulares, que luego fueron adoptadas por otros lenguajes. La mayoría de los matices en la construcción de patrones y modificadores (g, m, s, i, x, etc.) surgieron y se desarrollaron precisamente en Perl.
En la práctica, muchos desarrolladores utilizan incorrectamente cuantificadores codiciosos o se confunden con los modificadores (especialmente s y m), lo que conduce a resultados inesperados al reemplazar en textos de múltiples líneas o grandes datos. Los errores ocurren al esperar una coincidencia en la cadena, pero obtener otra, o al reemplazar solo la primera/última ocurrencia.
Es importante elegir y configurar correctamente los patrones y entender la acción de los modificadores. Los patrones codiciosos (por ejemplo, .*) capturan el rango máximo posible, mientras que los perezosos (por ejemplo, .*?) solo lo necesario mínimamente.
Trabajo con modificadores:
g — realiza el reemplazo para todas las coincidenciass — habilita el modo de procesamiento de cadenas de múltiples líneas, donde el punto (.) captura el símbolo de nueva líneam — cambia el comportamiento de los marcadores ^ y $Ejemplo — reemplazar etiquetas <tag> ... </tag> por un espacio solo una etiqueta a la vez (perezoso):
my $text = 'a <tag>1</tag> <tag>2</tag> b'; $text =~ s/<tag>.*?<\/tag>//g; print $text; # a b
Para procesar cadenas de múltiples líneas:
my $data = "Línea 1 Línea 2 <tag> DATOS </tag> Fin"; $data =~ s/<tag>.*?<\/tag>//gs; print $data;
Características clave:
s permite que el punto (.) capture saltos de líneag afecta la cantidad de reemplazos realizados¿Qué sucederá si no se indica ? después del codicioso . al procesar múltiples etiquetas?*
El cuantificador codicioso capturará el rango máximo posible, incluyendo etiquetas intermedias, lo que resultará en la eliminación inesperada de todo entre la primera <tag> y la última </tag>:
my $txt = 'A <tag>1</tag> <tag>2</tag> B'; $txt =~ s/<tag>.*<\/tag>//g; print $txt; # A B
Aquí se reemplazó toda la sección entre la primera <tag> y la última </tag>.
¿Cuál es la diferencia entre el modificador m y el modificador s en expresiones regulares de Perl?
s — el punto (.) captura el carácter de nueva línea; m — cambia los anclajes ^ y $ para trabajar dentro de las líneas de texto multilinea. Tienen propósitos diferentes, pero a menudo se confunden.
my $s = "abc def"; # /^def/ no funcionará sin m print $s =~ /^def/m; # 1 (verdadero)
¿Cómo manejar todas las ocurrencias del patrón si se aplica s/// solo una vez?
Sin el modificador g, solo se reemplazará la primera ocurrencia. Debes agregar g para un reemplazo global:
my $s = "foo bar foo"; $s =~ s/foo/baz/g; # reemplaza ambos foo
El desarrollador escribe un reemplazo para etiquetas HTML así:
$text =~ s/<tag>.*<\/tag>//g;
Como resultado, se eliminan todas las etiquetas junto con el contenido entre ellas — no cada una por separado.
Pros:
Contras:
Usar un patrón perezoso y modificadores correctos:
$text =~ s/<tag>.*?<\/tag>//gs;
Pros:
Contras: