¿Qué caracteres especiales deben escapar en las expresiones regulares?

Estoy cansado de intentar siempre adivinar si debería escapar de personajes especiales como ‘ ()[]{}| ‘etc. al usar muchas implementaciones de expresiones regulares.

Es diferente con, por ejemplo, Python, sed, grep, awk, Perl, rename, Apache, find, etc. ¿Existe algún conjunto de reglas que indique cuándo debo, y cuándo no debería, escapar de los personajes especiales? ¿Depende del tipo de expresiones regulares, como PCRE, POSIX o expresiones regulares extendidas?

Los personajes que debes y de los que no debes escapar dependen del sabor regex con el que estés trabajando.

Para PCRE y la mayoría de los otros sabores compatibles con Perl, escapa estas clases de caracteres externas:

 .^$*+?()[{\| 

y estas clases de personajes internos:

 ^-]\ 

Para las expresiones regulares extendidas POSIX (ERE), escapa estas clases de caracteres exteriores (igual que PCRE):

 .^$*+?()[{\| 

Escapar cualquier otro carácter es un error con POSIX ERE.

Dentro de las clases de caracteres, la barra invertida es un carácter literal en expresiones regulares POSIX. No puedes usarlo para escapar de nada. Debe usar “ubicación inteligente” si desea incluir metacaracteres de clases de caracteres como literales. Coloque el ^ en cualquier lugar, excepto al comienzo, el] al inicio y el – al comienzo o al final de la clase de caracteres para que coincida con estos literalmente, por ejemplo:

 []^-] 

En las expresiones regulares básicas de POSIX (BRE), estos son metacaracteres de los que debe escapar para suprimir su significado:

 .^$* 

Escapar paréntesis y llaves en BRE les da el significado especial que tienen sus versiones no guardadas en ERE. Algunas implementaciones (por ejemplo, GNU) también dan un significado especial a otros personajes cuando escapan, como \? y +. Escapar un carácter que no sea. ^ $ * () {} Normalmente es un error con BRE.

Dentro de las clases de caracteres, los BRE siguen la misma regla que los ERE.

Si todo esto hace que tu cabeza gire, toma una copia de RegexBuddy . En la pestaña Crear, haga clic en Insertar token y luego en Literal. RegexBuddy agregará escapes según sea necesario.

Modern RegEx Flavors (PCRE)

Incluye C, C ++, Delphi, EditPad, Java, JavaScript, Perl, PHP (preg), PostgreSQL, PowerGREP, PowerShell, Python, REALbasic, Real Studio, Ruby, TCL, VB.Net, VBScript, wxWidgets, XML Schema, Xojo, XRegExp.
La compatibilidad PCRE puede variar

En cualquier lugar:. . ^ $ * + - ? ( ) [ ] { } \ |


Legado RegEx Sabores (BRE / ERE)

Incluye awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed.
La compatibilidad con PCRE puede habilitarse en versiones posteriores o mediante el uso de extensiones

ERE / awk / egrep / emacs

Fuera de una clase de personaje:. . ^ $ * + ? ( ) [ { } \ |
Dentro de una clase de personaje: ^ - [ ]

BRE / ed / grep / sed

Fuera de una clase de personaje:. . ^ $ * [ \
Dentro de una clase de personaje: ^ - [ ]
Para los literales, no escape: + ? ( ) { } | + ? ( ) { } |
Para el comportamiento estándar de expresiones regulares, escape: \+ \? \( \) \{ \} \| \+ \? \( \) \{ \} \|


Notas

  • Si no está seguro de un carácter específico, se puede escapar como \xFF
  • Los caracteres alfanuméricos no se pueden escapar con una barra invertida
  • Los símbolos arbitrarios se pueden escapar con una barra diagonal inversa en PCRE, pero no BRE / ERE (solo se deben escapar cuando sea necesario). Para PCRE ] - solo es necesario escapar dentro de una clase de personaje, pero los mantuve en una sola lista para simplificar
  • Las cadenas de expresión citadas también deben tener los caracteres de comillas circundantes escapados y, a menudo, con las barras diagonales inversas dobladas (como "(\")(/)(\\.)" Versus /(")(\/)(\.)/ en JavaScript)
  • Además de los escapes, las diferentes implementaciones de expresiones regulares pueden admitir diferentes modificadores, clases de caracteres, anclas, cuantificadores y otras características. Para obtener más información, consulte regular-expressions.info , o use regex101.com para probar sus expresiones en vivo

Lamentablemente, no existe un conjunto de códigos de escape, ya que varía en función del idioma que está utilizando.

Sin embargo, mantener una página como la Página de Herramientas de Expresión Regular o esta Hoja de Referencia de Expresión Regular puede ser de gran ayuda para filtrar rápidamente las cosas.

POSIX reconoce variaciones múltiples en expresiones regulares – expresiones regulares básicas (BRE) y expresiones regulares extendidas (ERE). E incluso entonces, hay peculiaridades debido a las implementaciones históricas de las utilidades estandarizadas por POSIX.

No hay una regla simple para cuándo usar qué notación, o incluso qué notación utiliza un comando determinado.

Consulte el libro Mastering Regular Expressions de Jeff Friedl.

Desafortunadamente, el significado de cosas como (y \ (se intercambian entre las expresiones regulares del estilo de Emacs y la mayoría de los otros estilos. Por lo tanto, si intentas escapar de ellas, puedes estar haciendo lo contrario de lo que deseas).

Entonces, realmente debes saber qué estilo estás tratando de citar.

A veces, el simple escape no es posible con los personajes que has enumerado. Por ejemplo, usar una barra invertida para escapar de un paréntesis no va a funcionar en el lado izquierdo de una cadena de sustitución en sed, concretamente

 sed -e 's/foo\(bar/something_else/' 

Tiendo a usar una definición de clase de carácter simple en su lugar, por lo que la expresión anterior se convierte

 sed -e 's/foo[(]bar/something_else/' 

que encuentro que funciona para la mayoría de las implementaciones de expresiones regulares.

Por cierto, las clases de caracteres son componentes de expresiones regulares bastante vagas, por lo que tienden a funcionar en la mayoría de las situaciones en las que necesitas caracteres escapados en las expresiones regulares.

Editar: Después del comentario siguiente, simplemente pensé que mencionaría el hecho de que también debe considerar la diferencia entre los autómatas de estados finitos y los autómatas de estados no finitos al observar el comportamiento de la evaluación de expresiones regulares.

Tal vez le interese consultar “el shiny libro de bolas”, también conocido como Effective Perl ( enlace desinfectado de Amazon ), específicamente el capítulo sobre expresiones regulares, para tener una idea de la diferencia en los tipos de evaluación del motor de expresiones regulares.

¡No todo el mundo es PCRE!

De todos modos, ¡las expresiones regulares son tan torpes en comparación con SNOBOL ! ¡Ese fue un curso de progtwigción interesante! Junto con el de Simula .

¡Ah, las alegrías de estudiar en la UNSW a fines de los 70! (-:

Realmente, no hay. hay alrededor de medio billón de syntax de expresiones regulares distintas; parece que descienden a Perl, EMACS / GNU y AT & T en general, pero siempre me sorprende.

Para PHP, “siempre es seguro preceder a un no alfanumérico con” \ “para especificar que representa a sí mismo”. – http://php.net/manual/en/regexp.reference.escape.php .

Excepto si es un “o”.: /

Para escapar de las variables de patrón de expresión regular (o de las variables parciales) en PHP use preg_quote ()