El carácter "$" en Regex no significa "fin de cadena"
Disputa central: qué significa $
- El hilo gira en torno al hecho de que, en muchos motores,
$en modo no multilinea coincide con el final de la cadena o justo antes de un\nfinal, no estrictamente con el “fin de la cadena”. - Algunos motores (JS, Go, Rust, estilo RE2) hacen que
$sea equivalente a “fin de cadena” cuando multilinea está desactivado. - Otros (Python, Java, C#, PHP, Perl, PCRE, etc.) tratan
$más como “fin de línea”, con un caso especial para un único salto de línea final. - Varios comentaristas encuentran sorprendente y “whacky” el comportamiento de estilo Python/Perl, especialmente ejemplos como que
cat$no coincida concat\n\n.
Semántica de línea frente a cadena
- Un gran subhilo debate si
$es conceptualmente “fin de línea” o “fin de cadena”. - Un lado insiste en que la visión histórica, basada en líneas (de editores,
ed/sed/grep), justifica que$trate de forma especial un salto de línea final. - El otro lado replica que la mayoría de las APIs toman cadenas arbitrarias, no líneas, así que es razonable que los usuarios esperen que
$signifique “fin de cadena”. - Hay debate sobre las definiciones POSIX de “línea”, “línea incompleta” y sobre cómo un salto de línea como terminador frente a separador debería afectar a
$.
Dialectos de regex y (falta de) estandarización
- Muchos señalan que no existe un único estándar de regex; hay múltiples familias:
- POSIX BRE/ERE, con semánticas distintas para los anclajes.
- Perl/PCRE y descendientes (PHP, muchos lenguajes, PCRE2).
- Estilo RE2, usado por Go y la crate
regexde Rust, que evita deliberadamente algunas rarezas de Perl. - Regex de JavaScript ECMA, con sus propias lagunas y características.
- Se mencionan C++
<regex>, ECMA-262, POSIX y un RFC reciente (I-Regexp) como especificaciones formales, pero coexisten en lugar de unificar el comportamiento.
Implicaciones de seguridad y corrección
- Que
$coincida antes de un salto de línea final ha provocado errores reales, por ejemplo en validación de entrada en Ruby y en vulnerabilidades de ExifTool/GitLab, donde atacantes introducen payloads tras un salto de línea. - Recomendación de varios comentarios: cuando realmente quieras “cadena completa”, usa
\A...\Zo\zdonde estén disponibles, no^...$.
Herramientas, patrones de uso y ergonomía
- Muchos aconsejan comprobar siempre la documentación del motor concreto y probar las regex explícitamente.
- Algunos prefieren herramientas orientadas a líneas (
grep/sed/awk, editores como Vim) y piensan en términos de líneas; otros trabajan principalmente con cadenas en memoria y esperan semántica de cadena. - También aparece frustración más amplia por la fragmentación de sabores de regex, las reglas de escape y el soporte inconsistente para clases de caracteres y anclajes.