stringtranslate.com

Expresiones regulares compatibles con Perl

Perl Compatible Regular Expressions ( PCRE ) es una biblioteca escrita en C que implementa un motor de expresiones regulares inspirado en las capacidades del lenguaje de programación Perl . Philip Hazel comenzó a escribir PCRE en el verano de 1997. [3] La sintaxis de PCRE es mucho más potente y flexible que cualquiera de las variantes de expresiones regulares POSIX (BRE, ERE) [4] y que la de muchas otras bibliotecas de expresiones regulares.

Aunque PCRE originalmente tenía como objetivo la equivalencia de características con Perl, las dos implementaciones no son totalmente equivalentes. Durante la fase de PCRE 7.x y Perl 5.9.x, los dos proyectos coordinaron el desarrollo y las características se trasladaron entre ellos en ambas direcciones. [5]

En 2015, se lanzó una bifurcación de PCRE con una interfaz de programación (API) revisada. El software original, ahora llamado PCRE1 (la serie 1.xx–8.xx), ha tenido errores corregidos, pero no se ha realizado ningún desarrollo adicional. A partir de 2020 , se considera obsoleto y es probable que la versión actual 8.45 sea la última. El nuevo código PCRE2 (la serie 10.xx) ha tenido una serie de extensiones y mejoras de codificación y es donde se lleva a cabo el desarrollo.

Varios programas de código abierto importantes , como los servidores HTTP Apache y Nginx , y los lenguajes de programación PHP y R , incorporan la biblioteca PCRE; el software propietario puede hacer lo mismo, ya que la biblioteca tiene licencia BSD. A partir de Perl 5.10, PCRE también está disponible como reemplazo del motor de expresiones regulares predeterminado de Perl a través del re::engine::PCREmódulo.

La biblioteca se puede crear en Unix, Windows y otros entornos. PCRE2 se distribuye con un contenedor POSIX C, [Nota 1] varios programas de prueba y el programa de utilidad pcregrep/ pcre2grepque se crea junto con la biblioteca.

Características

Compilador justo a tiempoapoyo

Esta función opcional está disponible si se habilita cuando se crea la biblioteca PCRE2. Se pueden lograr grandes beneficios en el rendimiento cuando (por ejemplo) el programa que realiza la llamada utiliza la función con patrones compatibles que se ejecutan repetidamente. La compatibilidad con el compilador Just-in-Time fue escrita por Zoltan Herczeg y no se aborda en el contenedor POSIX.

Gestión de memoria flexible

El uso de la pila del sistema para realizar un seguimiento puede ser problemático en PCRE1, por lo que esta característica de la implementación se modificó en PCRE2. Ahora se utiliza el montón para este propósito y se puede limitar la cantidad total. El problema del desbordamiento de pila , que surgía regularmente con PCRE1, ya no es un problema con PCRE2 a partir de la versión 10.30 (2017).

Reglas de escape consistentes

Al igual que Perl, PCRE2 tiene reglas de escape consistentes: cualquier carácter no alfanumérico puede ser escapado para significar su valor literal anteponiendo una \(barra invertida) antes del carácter. Cualquier carácter alfanumérico precedido por una barra invertida normalmente le da un significado especial. En el caso en que la secuencia no se haya definido como especial, se produce un error. Esto es diferente a Perl, que da un error solo si está en modo de advertencia (PCRE2 no tiene un modo de advertencia). En las expresiones regulares POSIX básicas, a veces las barras invertidas escapaban a los caracteres no alfanuméricos (por ejemplo, \.), y a veces introducían una característica especial (por ejemplo, \(\)).

Clases de personajes extendidas

Además de los nombres POSIX más largos, se admiten clases de caracteres de una sola letra . Por ejemplo, \dcoincide con cualquier dígito exactamente como [[:digit:]]lo haría en expresiones regulares POSIX.

Coincidencia mínima (también conocida como "poco codiciosa")

Se puede colocar una A ?después de cualquier cuantificador de repetición para indicar que se debe utilizar la coincidencia más corta. El valor predeterminado es intentar la coincidencia más larga primero y retroceder a través de coincidencias más cortas: por ejemplo, a.*?bcoincidiría primero con "ab" en "ababab", donde a.*bcoincidiría con la cadena completa.

USi se establece la bandera, entonces los cuantificadores son no codiciosos (perezosos) de manera predeterminada, mientras que ?los hace codiciosos.

Propiedades de los caracteres Unicode

Unicode define varias propiedades para cada carácter. Los patrones en PCRE2 pueden coincidir con estas propiedades: p. ej. coincidiría con una cadena que comience con cualquier "puntuación de apertura" y termine con cualquier "puntuación de cierre", como . La coincidencia de ciertos metacaracteres "normales" puede ser impulsada por propiedades Unicode cuando se establece la opción de compilación PCRE2_UCP. La opción se puede establecer para un patrón al incluir al comienzo del patrón. La opción altera el comportamiento de los siguientes metacaracteres: , , , , , , , , y algunas de las clases de caracteres POSIX. Por ejemplo, el conjunto de caracteres coincidentes con (caracteres de palabra) se expande para incluir letras y letras acentuadas según lo definido por las propiedades Unicode. Tal coincidencia es más lenta que la alternativa normal ( solo ASCII ) no UCP. Tenga en cuenta que la opción UCP requiere que la biblioteca se haya creado para incluir compatibilidad con Unicode (este es el valor predeterminado para PCRE2). Las versiones muy tempranas de PCRE1 solo admitían código ASCII. Más tarde, se agregó compatibilidad con UTF-8. La compatibilidad con UTF-16 se agregó en la versión 8.30 y la compatibilidad con UTF-32 en la versión 8.32. PCRE2 siempre ha admitido las tres codificaciones UTF.\p{Ps}.*?\p{Pe}[abc](*UCP)\B\b\D\d\S\s\W\w\w

Coincidencia de múltiples líneas

^y $puede coincidir al principio y al final de una cadena solamente, o al principio y al final de cada "línea" dentro de la cadena, dependiendo de las opciones configuradas.

Opciones de nueva línea/salto de línea

Cuando se compila PCRE, se selecciona un salto de línea predeterminado. El salto de línea o nueva línea que esté en efecto afecta dónde PCRE detecta ^los comienzos y $finales de línea (en modo multilínea), así como qué coincide con el punto (independientemente del modo multilínea, a menos que (?s)se establezca la opción dotall). También afecta el procedimiento de coincidencia de PCRE (desde la versión 7.0): cuando un patrón no anclado no coincide al comienzo de una secuencia de nueva línea, PCRE avanza más allá de toda la secuencia de nueva línea antes de volver a intentar la coincidencia. Si la alternativa de opción de nueva línea en efecto incluye CRLF como uno de los saltos de línea válidos, no omite el \nen un CRLF si el patrón contiene referencias \ro específicas \n(desde la versión 7.3). Desde la versión 8.10, el metacarácter \Nsiempre coincide con cualquier carácter que no sean caracteres de salto de línea. Tiene el mismo comportamiento que .cuando la opción dotall aka (?s)no está en efecto.

La opción de nueva línea se puede modificar con opciones externas cuando se compila PCRE y cuando se ejecuta. Algunas aplicaciones que utilizan PCRE proporcionan a los usuarios los medios para aplicar esta configuración a través de una opción externa. Por lo tanto, la opción de nueva línea también se puede indicar al comienzo del patrón utilizando una de las siguientes opciones:

Cuando no está en modo UTF-8, los saltos de línea correspondientes se pueden hacer coincidir con [Nota 2] o .(?:\r\n?|\n|\x0B|\f|\x85)\R

En el modo UTF-8, se reconocen dos caracteres adicionales como saltos de línea con (*ANY):

En Windows, en datos que no son Unicode, algunos de los ANYcaracteres de salto de línea tienen otros significados.

Por ejemplo, \x85puede coincidir con una elipsis horizontal y, si se encuentra mientras la ANYnueva línea está vigente, activará el procesamiento de la nueva línea.

Vea a continuación la configuración y las opciones relacionadas con lo que coincide con la barra invertida-R.

Opciones de barra invertida-R

Cuando se compila PCRE, se selecciona un valor predeterminado para lo que coincide con \R. El valor predeterminado puede ser que coincida con los saltos de línea correspondientes a ANYCRLF o con los correspondientes a ANY. El valor predeterminado se puede anular cuando sea necesario incluyendo (*BSR_UNICODE)o (*BSR_ANYCRLF)al comienzo del patrón. Al proporcionar una (*BSR..)opción, también puede proporcionar una opción, por ejemplo, . Las opciones de barra invertida-R también se pueden cambiar con opciones externas por la aplicación que llama a PCRE2, cuando se compila un patrón.(*newline)(*BSR_UNICODE)(*ANY)rest-of-pattern

Inicio de las opciones de patrón

Opciones de salto de línea como (*LF)las documentadas anteriormente; opciones de barra invertida-R como (*BSR_ANYCRLF)las documentadas anteriormente; opción de Propiedades de caracteres Unicode (*UCP)documentada anteriormente; (*UTF8)opción documentada de la siguiente manera: si su biblioteca PCRE2 ha sido compilada con soporte UTF , puede especificar la (*UTF)opción al comienzo de un patrón en lugar de configurar una opción externa para invocar el modo UTF-8, UTF-16 o UTF-32.

Referencias anteriores

Un patrón puede hacer referencia a los resultados de una coincidencia anterior. Por ejemplo, (a|b)c\1coincidiría con "aca" o "bcb" y no coincidiría, por ejemplo, con "acb".

Subpatrones con nombre

Un subpatrón (rodeado de paréntesis, como (...)) puede nombrarse incluyendo un carácter inicial ?P<name>después del paréntesis de apertura. Los subpatrones nombrados son una característica que PCRE adoptó de las expresiones regulares de Python .

Esta característica fue adoptada posteriormente por Perl, por lo que ahora los grupos con nombre también se pueden definir utilizando (?<name>...)o (?'name'...), además de (?P<name>...). Los grupos con nombre se pueden referenciar hacia atrás con, por ejemplo: (?P=name)(sintaxis de Python) o \k'name'(sintaxis de Perl).

Subrutinas

Mientras que una referencia inversa proporciona un mecanismo para hacer referencia a esa parte del sujeto que ha coincidido previamente con un subpatrón, una subrutina proporciona un mecanismo para reutilizar un subpatrón subyacente previamente definido. Las opciones del subpatrón, como la independencia entre mayúsculas y minúsculas, se fijan cuando se define el subpatrón. (a.c)(?1)coincidiría con "aacabc" o "abcadc", mientras que el uso de una referencia inversa no lo haría, aunque ambos coincidirían con "aacaac" o "abcabc". PCRE también admite una construcción Oniguruma(a.c)\1 no perteneciente a Perl para subrutinas. Se especifican utilizando o .\g<subpat-number>\g<subpat-name>

Agrupamiento atómico

La agrupación atómica es una forma de evitar que se vuelva atrás en un patrón. Por ejemplo, a++bcse buscarán tantas "a" como sea posible y nunca se volverá atrás para probar una menos.

Afirmaciones de mirar hacia adelante y mirar hacia atrás

Los patrones pueden afirmar que el texto anterior o posterior contiene un patrón sin consumir el texto coincidente (afirmación de ancho cero). Por ejemplo, / \w+(?=\t)/ ​​coincide con una palabra seguida de una tabulación , sin incluir la tabulación en sí.

Las afirmaciones de look-behind no pueden tener una longitud incierta aunque (a diferencia de Perl) cada rama puede tener una longitud fija diferente.

\Kse puede utilizar en un patrón para restablecer el inicio de la coincidencia completa actual. Esto proporciona un enfoque alternativo flexible a las afirmaciones retrospectivas porque la parte descartada de la coincidencia (la parte que precede \Ka ) no necesita tener una longitud fija.

Secuencias de escape para afirmaciones de ancho cero

Por ejemplo, \bpara hacer coincidir "límites de palabras" de ancho cero, similar a .(?<=\W)(?=\w)|(?<=\w)(?=\W)|^|$

Comentarios

Un comentario comienza (?#y termina en el siguiente paréntesis de cierre.

Patrones recursivos

Un patrón puede hacer referencia a sí mismo de forma recursiva o a cualquier subpatrón. Por ejemplo, el patrón coincidirá con cualquier combinación de paréntesis equilibrados y "a".\((a*|(?R))*\)

Llamadas genéricas

Las expresiones PCRE pueden incorporar , donde n es un número. Esto llamará a una función externa definida por el usuario a través de la API PCRE y se puede utilizar para incorporar código arbitrario en un patrón.(?Cn)

Diferencias con Perl

Las diferencias entre PCRE2 y Perl (a partir de Perl 5.9.4) incluyen, entre otras: [6]

Hasta la versión 10.30, las coincidencias recursivas eran atómicas en PCRE y no atómicas en Perl.

Esto significaba que coincidiría en Perl pero no en PCRE2 hasta la versión 10.30."<<!>!>!>><>>!>!>!>" =~ /^(<(?:[^<>]+|(?3)|(?1))*>)()(!>!>!>)$/

El valor de un búfer de captura que se deriva del ?cuantificador (coincidencia 1 o 0 veces) cuando está anidado en otro búfer de captura cuantificado es diferente

En Perl dará como resultado que contiene "a" y que contiene , pero en PCRE dará como resultado que contiene "b"."aba" =~ /^(a(b)?)+$/;$1$2undef$2

PCRE permite que a los buffers de captura nombrados se les den nombres numéricos; Perl requiere que el nombre siga la regla de palabras simples

Esto significa que \g{}es inequívoco en Perl, pero potencialmente ambiguo en PCRE.

Esto ya no es una diferencia desde PCRE 8.34 (publicado el 15 de diciembre de 2013), que ya no permite que los nombres de grupos comiencen con un dígito. [7]

PCRE permite que las alternativas dentro del lookbehind tengan diferentes longitudes

Dentro de las afirmaciones de lookbehind, tanto PCRE como Perl requieren patrones de longitud fija.

Es decir, tanto PCRE como Perl no permiten patrones de longitud variable que utilicen cuantificadores dentro de afirmaciones de búsqueda hacia atrás.

Sin embargo, Perl requiere que todas las ramas alternativas de una afirmación de búsqueda hacia atrás tengan la misma longitud entre sí, mientras que PCRE permite que esas ramas alternativas tengan longitudes diferentes entre sí siempre que cada rama tenga una longitud fija.

PCRE no admite ciertas construcciones "experimentales" de Perl

Tal como (??{...})(una devolución de llamada cuyo retorno se evalúa como parte del patrón) ni la (?{})construcción, aunque esta última se puede emular usando (?Cn).

Los verbos de control de recursión agregados en la serie Perl 5.9.x tampoco son compatibles.

El soporte para verbos de control de retroceso experimentales (agregados en Perl 5.10) está disponible en PCRE desde la versión 7.3.

Son (*FAIL), (*F), (*PRUNE), (*SKIP), (*THEN), (*COMMIT), y (*ACCEPT).

El uso correspondiente de argumentos de Perl con verbos de control de retroceso generalmente no es compatible.

Sin embargo, tenga en cuenta que desde la versión 8.10, PCRE admite los siguientes verbos con un argumento específico: (*MARK:markName), (*SKIP:markName), (*PRUNE:markName), y (*THEN:markName).

Desde la versión 10.32, PCRE2 ha admitido (*ACCEPT:markName), (*FAIL:markName), y (*COMMIT:markName).

PCRE y Perl son ligeramente diferentes en su tolerancia a las construcciones erróneas.

Perl permite cuantificadores en el (?!...)constructo, lo cual no tiene sentido pero es inofensivo (aunque ineficiente); PCRE produce un error en versiones anteriores a 8.13.

PCRE tiene un límite estricto en la profundidad de recursión, Perl no.

Con las opciones de compilación predeterminadas no se podrá coincidir debido al límite, pero Perl lo hará correctamente."bbbbXcXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" =~ /.X(.+)+X/

Perl utiliza el montón para la recursión y no tiene un límite estricto para la profundidad de la recursión, mientras que PCRE2 tiene un límite predeterminado en tiempo de compilación que puede ajustarse hacia arriba o hacia abajo mediante la aplicación que realiza la llamada.

Verificación

Con la excepción de los puntos anteriores, PCRE es capaz de pasar las pruebas en el t/op/re_testsarchivo " " de Perl, una de las principales pruebas de regresión a nivel de sintaxis para el motor de expresiones regulares de Perl.

Véase también

Notas y referencias

Notas

  1. ^ La biblioteca principal PCRE2 proporciona funcionalidades de coincidencia y de coincidencia y reemplazo.
  2. ^ ¿ Seguro que la parte no es ? (es decir , como U+0085  != 0x85) Advertencia : si el patrón no funcionó: experimente con las configuraciones Unicode de la implementación de RegEx o intente sustituir con lo siguiente:\x85\xC2\x85(?:\r\n?|\n|\x0B|\f|\xC2\x85)

    \xC2\x85
    • \x{0085}
    • \u0085

Referencias

[8]

  1. ^ Versión final de PCRE1: https://lists.exim.org/lurker/message/20210615.162400.c16ff8a3.en.html
  2. ^ Lanzamientos: https://github.com/PCRE2Project/pcre2/releases
  3. ^ Exim y PCRE: Cómo el software libre secuestró mi vida (1999-12), por Philip Hazel , pág. 7: https://www.ukuug.org/events/winter99/proc/PH.ps

    ¿Qué pasa con PCRE?

    • Escrito en el verano de 1997, publicado en el sitio FTP.
    • La gente lo encontró y comenzó una lista de correo.
    • Se han producido un flujo constante de mejoras.
  4. ^
    • Expresión regular - Estándar POSIX (Búsqueda de Google): https://www.google.com/search?num=100&q=%22Regular+Expression%22%7C%22Regular+Expressions%22%7C%22RegEx%22%7C%22RegExp%22+site%3Apubs.opengroup.org+inurl%3Aonlinepubs%2F9699919799+-intitle%3A%22Index+of+% 2Fonlinepubs%22+-inurl%3Aidx+-inurl%3Acontents.html+-inurl%3Atoc.html+-inurl%3A9699919799.orig+-inurl%3A2008edition+-inurl%3A2013edition+-inurl%3A2016edition+-inurl%3A2018edition
    • Utilidades § Notación de coincidencia de patrones: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html#tag_18_13
    • Definiciones básicas § Expresiones regulares básicas: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap09.html#tag_09_03
    • Fundamento § Expresiones regulares: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/xrat/V4_xbd_chap09.html#tag_21_09
  5. ^ PCRE2 - Expresiones regulares compatibles con Perl (API revisada) (2020), por la Universidad de Cambridge : https://pcre.org/pcre2.txt
  6. ^ Diferencias entre PCRE2 y Perl (13 de julio de 2019), por Philip Hazel : https://www.pcre.org/current/doc/html/pcre2compat.html
  7. ^ Cita del registro de cambios de PCRE (https://www.pcre.org/original/changelog.txt): "Perl ya no permite que los nombres de grupos comiencen con dígitos, por lo que he realizado este cambio también en PCRE".
  8. ^ Registro de cambios para PCRE2: https://www.pcre.org/changelog.txt

Enlaces externos