En los datos de procesamiento , una expresión regular o regular de expresión o expresión normal o patrón , es una cadena de caracteres , que describe, de acuerdo con una sintaxis precisa, un conjunto de posibles cadenas de caracteres. Las expresiones regulares también se denominan regex (una palabra combinada formada a partir de expresiones regulares en inglés ). Las expresiones regulares provienen de las teorías matemáticas de los lenguajes formales de la década de 1940. Su capacidad para describir de manera concisa conjuntos regulares explica por qué se encontraron en varios campos científicos en los años de la posguerra y justifica su adopción en la informática . Las expresiones regulares se utilizan hoy en día para programar software con funcionalidades para leer, controlar, modificar y analizar textos, así como en la manipulación de lenguajes formales como los lenguajes informáticos .
Estas expresiones regulares tienen la cualidad de poder describirse mediante fórmulas o patrones, (en patrones en inglés ) mucho más simples que los otros medios.
En la década de 1940 , Warren McCulloch y Walter Pitts describieron el sistema nervioso modelando neuronas mediante simples autómatas. En 1956, el lógico Stephen Cole Kleene describió estos modelos en términos de conjuntos regulares y autómatas . Se le considera el inventor de expresiones regulares. En 1959, Michael O. Rabin y Dana Scott ofrecieron el primer tratamiento matemático y riguroso de estos conceptos, lo que les valió el Premio Turing en 1976.
En este contexto, las expresiones regulares corresponden a gramáticas de tipo 3 (ver Gramática formal ) de la jerarquía de Chomsky ; por tanto, pueden utilizarse para describir la morfología de una lengua .
Ken Thompson implementó la notación de Kleene en el editor qed , luego en el editor ed en Unix y finalmente en grep . Desde entonces, las expresiones regulares se han utilizado ampliamente en utilidades como lex, así como en lenguajes de programación nacidos bajo Unix como expr , awk , Perl , Tcl , Python , etc.
Saliendo del marco teórico, las expresiones regulares han adquirido funcionalidades que permiten la descripción de lenguajes no racionales. Se ha producido así un cambio semántico: la noción de expresión regular no tiene el mismo significado en el contexto de la informática aplicada y en la teoría de los lenguajes formales.
Expresión regular | Palabras descritas | Palabras no descritas |
---|---|---|
detectado | "Detectado" | "Detectado", "detectado", "detectado", "" |
ex- (a? e | æ | é) quo | "Ex-equo", "ex-equo", "ex-aequo" y "ex-æquo" |
"Ex-quo", "ex-aiquo", "ex-aeko", "ex-æéquo" |
^ Sección. + | "Sección 1", "Sección 22", "Sección A", ... |
"Ver Sección 1", " Sección " |
$ 6.66 * | "6.6", "6.666", "6.6666", ... |
"6.66667", |
[1234567890] + (, [1234567890] +)? | "2", "42", "0,618", "49,3", ... |
"3,", ", 75", "" |
Creadas originalmente para describir lenguajes formales, las expresiones regulares se utilizan en el análisis y manipulación de lenguajes informáticos ; Por tanto, los compiladores e intérpretes se basan en ellos.
Utilizada como las herramientas de búsqueda de texto en un documento, una expresión regular describe cadenas de caracteres que tienen propiedades comunes, con el fin de encontrarlos en un bloque de texto para aplicar un tratamiento automatizado, como una adición, su reemplazo, modificación o eliminación.
Muchos editores de texto y la mayoría de los entornos de desarrollo integrados admiten expresiones regulares. Un gran número de utilidades de Unix saben cómo utilizarlas de forma nativa. Los más conocidos son GNU grep o GNU sed que, como los editores de texto, utilizan estas expresiones para navegar automáticamente por un documento en busca de fragmentos de texto compatibles con el patrón de búsqueda, y posiblemente para agregar, sustituir o eliminar.
Las interfaces de línea de comando (o shells ) utilizan un sistema relacionado pero separado y menos expresivo llamado glob (en) o globbing.
Las expresiones regulares se utilizan con frecuencia en la administración de sistemas , el desarrollo de software y las actividades de procesamiento del lenguaje natural . Vieron un nuevo campo de aplicación con el desarrollo de Internet y la difusión de códigos maliciosos o mensajes de spam . Los filtros y robots que utilizan estas expresiones se utilizan para detectar elementos potencialmente dañinos.
En la teoría del lenguaje formal , una expresión regular es una expresión que representa un lenguaje racional . En este contexto, las expresiones regulares tienen un poder expresivo más limitado: esta noción tiene un significado más amplio en la computación aplicada que en la teoría del lenguaje formal.
Una expresión regular es una serie de caracteres tipográficos (que se llama más simplemente "patrón" - " patrón " en inglés) que describen un conjunto de cadenas de caracteres . Por ejemplo, el conjunto de palabras "atado, atado, atado y atado" se puede condensar en un solo patrón "ex- (a? E | æ | é) quo". Los mecanismos básicos para formar tales expresiones se basan en caracteres especiales de sustitución, agrupación y cuantificación.
Una barra vertical generalmente separa dos expresiones alternativas: "equo | aequo" designa equo o aequo. También es posible utilizar paréntesis para definir el campo y la prioridad de detección, "(ae | e) quo" designando el mismo conjunto como "aequo | equo" y cuantificar los grupos presentes en el patrón añadiendo caracteres de cuantificación a el derecho de estas agrupaciones.
Los cuantificadores más comunes son:
Los símbolos con semántica particular pueden denominarse "operadores", "metacaracteres" o "caracteres especiales". Los caracteres que solo se representan a sí mismos se denominan "literales".
Las expresiones regulares se pueden combinar, por ejemplo, mediante concatenación , para producir expresiones regulares más complejas.
Cuando una cadena de caracteres coincide con la descripción dada por la expresión regular, decimos que hay una "coincidencia" entre la cadena y el patrón, o que el patrón "coincide" con la cadena. Esta correspondencia puede afectar a la totalidad o parte de la cadena de caracteres. Por ejemplo, en la frase “Los dos equipos terminaron empatados y se saludaron. ", La subcadena" ex-æquo "se corresponde con el patrón" ex- (a? E | æ | é) quo ".
De forma predeterminada, las expresiones regulares distinguen entre mayúsculas y minúsculas . Cuando es posible, intentan hacer coincidir la subcadena más grande correspondiente al patrón: se dice que son "codiciosos". Por ejemplo, Aa+reconoce la cadena completa "Aaaaaaa" en lugar de una parte "Aaa" (glotonería), pero no reconoce la cadena "aaaA" (distinción entre mayúsculas y minúsculas).
Operadores | Descripción | Ejemplos de | ||
---|---|---|---|---|
Expresión regular | Cadenas descritas | Canales no descritos | ||
expr 1 expr 2 | Operador de concatenación de dos expresiones (implícito). | ab | "Ab" | "A", "b", cadena vacía |
. | Un personaje y uno | . | "A", "b", etc. | cadena vacía, "ab" |
expr ? | Este cuantificador corresponde a lo que le precede, presente cero o una vez . Si existen varias coincidencias en un texto, primero busca las que se encuentran al principio del texto y luego devuelve la mayor longitud posible desde esa posición inicial. | ¿a? | cadena vacía, "a" | "Aa", "b" |
expr + | Este cuantificador corresponde a lo que le precede, repetido una o más veces . Si existen varias coincidencias en un texto, primero busca las que se encuentran al principio del texto y luego devuelve la mayor longitud posible desde esa posición inicial. | a + | "A", "aa", "aaaaa", etc. | cadena vacía, "b", "aaab" |
expr * | Este cuantificador corresponde a lo que le precede, repetido cero o más veces . Si existen varias coincidencias en un texto, primero busca las que se encuentran al principio del texto y luego devuelve la mayor longitud posible desde esa posición inicial. | a* | cadena vacía, "a", "aaa", etc. | "B", "aaab" |
expr 1 | expr 2 | Es el operador de elección entre varias alternativas, es decir, la unión de conjuntos. Se puede combinar tantas veces como sea necesario para cada una de las posibles alternativas. Coincide con una de las expresiones colocadas antes o después del operador . Estas expresiones pueden opcionalmente estar vacías, por lo que (x |) es equivalente ax?. | a | b | "A", "b" | cadena vacía, "ab", "c" |
[ lista ] | Uno de los caracteres entre corchetes ("clase de carácter") | [a e i o u] | "A", "e", "i", etc. | cadena vacía, "b", "ae" |
[^ lista ] | Un carácter que no esté entre corchetes ("clase de carácter") | [^ aeiou] | "B", etc. | cadena vacía, "a", "bc" |
( expr ) | Agrupar la expresión entre paréntesis | (detectado) | "Detectado" | "Detectado", "detectado", "detectado" |
expr { n } | Exactamente n apariciones de la expresión que precede a las llaves | un {3} | "Aaa" | "Aa", "aaaa" |
expr { n , m } | Entre n y m apariciones de la expresión que precede a las llaves | a {2.4} | "Aa", "aaa", "aaaa" | "A", "aaaaa" |
expr { n ,} | Al menos n apariciones de la expresión que precede a las llaves | un {3,} | "Aaa", "aaaa", "aaaaa", etc. | "Automóvil club británico" |
^ | Este predicado no corresponde a ningún carácter pero fija una condición necesaria que permite llegar a un acuerdo sobre lo que le sigue al indicar que debe estar al principio de una línea (por lo tanto, estar al principio del texto de entrada o después de un salto de línea) . No se puede considerar de esa manera al comienzo de la expresión regular, en otros lugares se considera literalmente. Se aplica como condición al resto de la expresión regular (y por lo tanto concierne a todas las alternativas representadas). | ^ a encuentra "a" al principio de la línea, pero no en "ba". | ||
PS | Ce prédicat ne correspond à aucun caractère mais fixe une condition nécessaire permettant de trouver un accord sur ce qui le précède en indiquant que ce doit être à la fin d'une ligne (donc être à la fin du texte d'entrée ou juste avant un salto de línea). No se puede considerar de esa manera al final de la expresión regular, en otros lugares se considera literalmente. Se aplica como condición al resto de la expresión regular (y por lo tanto concierne a todas las alternativas representadas). | a $ encuentra "a" al final de la línea pero no en "ab". |
En informática, una herramienta para manipular expresiones regulares se denomina motor de expresiones regulares o motor de expresiones regulares . Existen estándares para garantizar la coherencia en el uso de estas herramientas.
El estándar POSIX ofrece tres conjuntos de estándares:
Las expresiones regulares en perl también son un estándar de facto, debido a su riqueza expresiva y poder. Si bien siguen su propio desarrollo, están, por ejemplo, en el origen de la biblioteca PCRE . ECMAScript también propone en el documento Estándar ECMA-262 un estándar utilizado, por ejemplo, por JavaScript .
Las notaciones o su semántica pueden variar ligeramente de un motor de expresión regular a otro. Pueden cumplir solo parcial o parcialmente con estos estándares, u ofrecer sus propias características, como GNU o .NET Framework . Los detalles de cada uno se discuten más adelante en este artículo.
Una clase de personaje es un conjunto de personajes. Se puede definir de diferentes formas:
Se pueden realizar uniones de clases de caracteres: [0-9ab]designa el conjunto formado por los caracteres "0" a "9" y las letras "a" y "b". Algunas bibliotecas también le permiten cruzar clases de caracteres.
Entre corchetes, los metacaracteres se interpretan literalmente: [.?*]designa el conjunto formado por los caracteres ". ","? "Y" * ".
Las clases de caracteres más utilizadas generalmente se suministran con el motor de expresiones regulares. En la siguiente tabla se hace un inventario de estas clases.
La biblioteca POSIX define clases inicialmente para ASCII y luego, por extensión, para otras formas de codificación de caracteres, según la configuración regional .
En Unicode y lenguajes como perl, los conjuntos de caracteres se definen mediante la noción de propiedades de caracteres. Esto permite designar un conjunto de caracteres según su categoría (ejemplos: letra, puntuación de apertura, puntuación de cierre, separador, carácter de control), según la dirección de escritura (por ejemplo, de izquierda a derecha o de derecha a izquierda), según el alfabeto (ejemplos: latín, cirílico, griego, hiragana); según la asignación de bloques, o incluso según los mismos principios que las clases de caracteres POSIX (sobre este tema, lea la sección Expresiones regulares y Unicode ).
POSIX | No estándar | perl, Python | Empuje | Java | Unicode | ASCII | Descripción |
---|---|---|---|---|---|---|---|
\p{ASCII} | [\x00-\x7F] | Caracteres ASCII | |||||
[:alnum:] | \p{Alnum} | A-Za-z0-9 | Caracteres alfanuméricos | ||||
[:word:] | \w | \w | \w | A-Za-z0-9_ | Caracteres alfanuméricos y "_" | ||
\W | \W | \W | ^A-Za-z0-9_ | Personajes que no forman palabras | |||
[:alpha:] | \a | \p{Alpha} | \p{L} o \p{Letter} | A-Za-z | Caracteres alfabéticos | ||
[:blank:] | \s | \p{Blank} | \t | Espacio y tabulación | |||
\b | \< \> | \b | (?<=\W)(?=\w)|(?<=\w)(?=\W) | Posiciones inicial y final de las palabras | |||
\B | \B | (?<=\W)(?=\W)|(?<=\w)(?=\w) | Posiciones que no corresponden al principio ni al final de una palabra. | ||||
[:cntrl:] | \p{Cntrl} | \p{Cc} o \p{Control} | \x00-\x1F\x7F | Personajes de control | |||
[:digit:] | \d | \d | \p{Digit} o \d | \p{Nd} o \p{Decimal_Digit_Number} | 0-9 | Dígitos decimales | |
\D | \D | \D | \P{Nd} o \P{Decimal_Digit_Number} | ^0-9 | Algo que no sea un decimal | ||
[:graph:] | \p{Graph} | \x21-\x7E | Caracteres visibles | ||||
[:lower:] | \l | \p{Lower} | \p{Ll} o \p{Lowercase_Letter} | a-z | Letras minusculas | ||
[:print:] | \p | \p{Print} | \x20-\x7E | Caracteres imprimibles | |||
[:punct:] | \p{Punct} | \p{P} o \p{Punctuation} | ][!"#$%&'()*+,./:;<=>?@\^_`{|}~- | Caracteres de puntuación | |||
[:space:] | \s | \_s | \p{Space} o \s | \p{Z} o \p{Separator} | \t\r\n\v\f | Personajes espaciales | |
\S | \S | \S | \P{Z} o \P{Separator} | ^ \t\r\n\v\f | Algo que no sea un personaje espacial | ||
[:upper:] | \u | \p{Upper} | \p{Lu} o \p{Uppercase_Letter} | A-Z | Letras mayúsculas | ||
[:xdigit:] | \x | \p{XDigit} | A-Fa-f0-9 | Dígitos hexadecimales | |||
\A | Inicio de la cadena de caracteres | ||||||
\Z | Fin de la cadena de caracteres |
Por ejemplo, en el estándar POSIX, [[:upper:]ab]coincide un carácter entre el conjunto formado por letras mayúsculas y minúsculas "a" y "b". En el estándar ASCII, esta expresión regular se escribiría [A-Zab].
La noción de clase de equivalencia no debe confundirse con la noción de clase de carácter.
Por ejemplo, en la configuración regional FR, la clase [= e =] agrupa todas las letras {e, é, è, ë, ê}.
Esto significa que cuando se clasifican, las letras {e, é, è, ë, ê} aparecen en el mismo conjunto de caracteres, después de la d y antes de la f .
La mayoría de los motores de estándares y expresiones regulares ofrecen funciones avanzadas. Especialmente :
Las notaciones utilizadas son muy variables. Este capítulo reúne, por un lado, las notaciones específicas de diferentes implementaciones y, por otro lado, la empresa de estandarización.
El estándar POSIX ha buscado remediar la proliferación de sintaxis y funcionalidad proporcionando un estándar de expresiones regulares configurables. Puede obtener una descripción general leyendo el manual para regexmuchos dialectos de Unix , incluido GNU / Linux . Sin embargo, incluso este estándar no incluye toda la funcionalidad agregada a las expresiones regulares de Perl.
Finalmente, POSIX agrega soporte para plataformas que utilizan un conjunto de caracteres no basado en ASCII, en particular EBCDIC , y soporte de locale parcial para algunos metacaracteres.
Expresiones regulares básicasLas utilidades en el mundo Unix como sed , GNU grep , ed o vi usan el estándar BRE (" Expresión regular básica ") de POSIX por defecto . En él, las llaves, los paréntesis, el símbolo "? "Y el símbolo" + "no son metacaracteres: solo se representan a sí mismos. Para tomar su semántica de los metacaracteres, deben escaparse con el símbolo "\".
Ejemplo: la expresión regular coincide con (ab.)+"(abc) +" pero no con "abcabd", que es \(ab.\)\+adecuada.
Expresiones regulares extendidasPOSIX Extended Regular Expression (ERE ) a menudo se admite en las utilidades de las distribuciones Unix y GNU / Linux al incluir el indicador -E en la invocación de la línea de comandos de estas utilidades. A diferencia de las expresiones regulares básicas, reconocen caracteres que antes se consideraban metacaracteres. Por lo tanto, deben evitarse para ser interpretados literalmente.
La mayoría de los ejemplos que se dan aquí son expresiones regulares extendidas POSIX.
Secuencias de escapeComo los personajes (, ), [, ], ., *, ?, +, ^, |, $, -y \se utilizan como símbolos especiales, deben ser referenciados en una secuencia de escape si literalmente se denotan el carácter correspondiente. Esto se hace precediéndolos con una barra invertida \.
Se usan extensiones similares en el editor emacs , que usa un conjunto de comandos diferente del estándar POSIX; pero usa las mismas expresiones regulares con una notación extendida. Las expresiones regulares extendidas ahora también son compatibles con vim , la versión mejorada de vi .
Operador extendido (no POSIX) | Descripción | Ejemplo |
---|---|---|
\{m,n\} | En la notación extendida, esto crea un cuantificador a medida limitada, lo que permite m a coincidir exactamente n ocurrencias de lo anterior, en donde m y n son dos números enteros tales que m < n . Cualquiera de los dos parámetros se puede omitir: si se omite el primer parámetro m , el valor predeterminado es 0; si se omite el segundo parámetro n , pero la coma está presente, se considera infinito; si se omite el segundo parámetro n , así como la coma separadora, toma el valor predeterminado igual al primer parámetro m . | Vea los ejemplos a continuación. |
\( \) | En notación extendida, los paréntesis de agrupación (en una secuencia de escape) se utilizan para delimitar un conjunto de alternativas, o cualquier subexpresión regular (excepto las condiciones de inicio y final de línea) para aplicar un cuantificador. Además, estos paréntesis delimitan un grupo de captura numerado que se puede usar para sustituciones (luego hacemos referencia a los grupos capturados en la cadena de sustitución con donde n es el número de grupo de captura entre 1 y 9, la cadena completa encontrada está representada por ). $n$& | Vea los ejemplos a continuación. |
Además, se agregan muchas otras secuencias de escape para indicar clases de caracteres predefinidas. Son específicos de cada utilidad o en ocasiones varían según la versión o la plataforma (sin embargo se mantienen estables durante mucho tiempo en emacs que fue un precursor de estas extensiones, que otros autores han implementado parcialmente de forma limitada o diferente).
Python usa expresiones regulares basadas en expresiones regulares POSIX, con algunas extensiones o diferencias.
Los elementos compatibles con POSIX son los siguientes:
La secuencia \bdesigna el carácter de retroceso ( 0x08con codificación compatible con ASCII) cuando se usa dentro de una clase de caracteres, y el límite de una palabra en caso contrario.
El sistema operativo BSD utiliza la biblioteca de expresiones regulares escrita por Henry Spencer . Compatible con el estándar POSIX 1003.2, esta biblioteca también es utilizada por MySQL (con los operadores REGEXP y NOT REGEXP) y PostgreSQL (con el operador “~” y sus variantes).
El motor de expresión regular del lenguaje Tcl proviene de desarrollos de Henry Spencer posteriores a los de la biblioteca BSD. Las expresiones regulares se denominan Expresiones regulares avanzadas (o ARE) y son ligeramente diferentes de las expresiones regulares extendidas en POSIX. También se admiten expresiones regulares básicas y extendidas.
A diferencia de otros motores, éste funciona en base a un PLC, lo que lo hace menos eficiente cuando son necesarias capturas o retrocesos , pero más eficiente en caso contrario.
Perl ofrece un conjunto de extensiones particularmente rico. Este lenguaje de programación tiene mucho éxito debido a la presencia de operadores de expresión regular incluidos en el propio lenguaje. Las extensiones que ofrece también están disponibles para otros programas bajo el nombre lib PCRE ( Expresiones regulares compatibles con Perl , literalmente biblioteca de expresiones regulares compatibles con Perl ). Esta biblioteca fue escrita originalmente para el servidor de correo Exim , pero ahora está asumida por otros proyectos como Python , Apache , Postfix , KDE , Analog , PHP y Ferite .
Las especificaciones de Perl 6 regularizan y amplían el mecanismo del sistema de expresión regular. Además, está mejor integrado en el lenguaje que en Perl 5. El control del retorno de la traza es muy fino allí. El sistema de expresiones regulares de Perl 6 es lo suficientemente potente como para escribir analizadores sin usar complementos de analizadores . Las expresiones regulares son una forma de subrutinas y las gramáticas son una forma de clase . El mecanismo se implementa en el ensamblador Parrot mediante el módulo PGE en la implementación Parrot de Perl 6 y en Haskell en la implementación Pugs . Estas implementaciones son un paso importante en la construcción de un compilador Perl 6 completo. Algunas de las características de Perl 6 regexp, como las capturas con nombre, están integradas desde Perl 5.10.
PHP admite dos formas de notaciones: la sintaxis POSIX (POSIX 1003.2) y la, mucho más rica y eficiente, de la biblioteca PCRE (Perl Compatible Regular Expression).
Una de las fallas criticadas en PHP está relacionada con su limitado soporte para cadenas de caracteres, aunque se utiliza principalmente para procesar texto, ya que el texto solo se puede representar en un conjunto de caracteres codificados en 8 bits, sin poder especificar claramente cuál se utiliza codificación. En la práctica, por lo tanto, es necesario agregar a PHP bibliotecas de soporte para codificar y decodificar textos, aunque solo sea para representarlos en UTF-8. Sin embargo, incluso en UTF-8, el problema surge inmediatamente con la semántica de las expresiones regulares, ya que los caracteres tienen una codificación de longitud variable, lo que requiere hacer que las expresiones regulares sean más complejas. Por lo tanto, se desarrollan extensiones opcionales de PHP para crear un nuevo tipo de datos para el texto, con el fin de facilitar su procesamiento (y eventualmente ser compatible con Perl6 que, como Haskell , tendrá de forma nativa soporte completo para Unicode).
ICU define una biblioteca portátil para el procesamiento de textos internacional. Esto se desarrolló primero en lenguaje C (versión denominada ICU4C) o para la plataforma Java (versión denominada ICU4J). Los puertos (o adaptaciones) también están disponibles en muchos otros lenguajes, utilizando la biblioteca desarrollada para el lenguaje C (o C ++ ).
Las expresiones regulares que se pueden usar en ICU toman las características de las expresiones regulares en Perl, pero las complementan para brindarles soporte completo para el juego de caracteres Unicode (vea la siguiente sección para preguntas relacionadas con la estandarización aún en progreso). También aclaran su significado al hacer que las expresiones regulares sean independientes del juego de caracteres codificados utilizado en los documentos, ya que el juego de caracteres Unicode se usa como codificación dinámica interna.
Esto se debe a que las expresiones regulares de Perl (o PCRE) no son portátiles para procesar documentos que utilizan diferentes conjuntos de caracteres codificados, ni admiten correctamente conjuntos de caracteres codificados de varios bytes (longitud variable) como ISO 2022 , Shift-JIS o UTF-8 ) , o codificado en una o más unidades binarias de más de 8 bits (por ejemplo, UTF-16 ) ya que la codificación real de estos conjuntos como secuencias de bytes depende de la plataforma. -forma utilizada para el procesamiento (orden de almacenamiento de bytes en un palabra de más de 8 bits).
ICU resuelve esto adoptando un procesamiento que utiliza internamente un único conjunto de 32 bits y admite el conjunto de caracteres universal completo (UCS), como se define en ISO / IEC 10646 y se especifica semánticamente en el estándar Unicode (que agrega al estándar el soporte de propiedades informativas o normativas sobre caracteres, y recomendaciones para el procesamiento automático de texto, algunas de estas recomendaciones son opcionales o informativas, otras se han convertido en estándar e integradas en el propio estándar Unicode, otras finalmente han adquirido el estatus de estándar internacional en ISO o estándar nacional en ciertos países).
ICU admite las siguientes extensiones, directamente en expresiones regulares o en la expresión regular de una clase de caracteres (entre […]):
Las expresiones regulares de ICU se encuentran actualmente entre las más poderosas y expresivas en el procesamiento de documentos multilingües. Son en gran parte la base de la estandarización (aún en curso) de las expresiones regulares Unicode (ver más abajo) y un subconjunto es compatible de forma nativa en la biblioteca de lenguaje estándar de Java (que utiliza internamente un juego de caracteres portátil para codificación variable, basado en UTF-16 con extensiones, y cuyas unidades de codificación son de 16 bits).
ICU es una biblioteca en evolución. En principio, debería adoptar todas las extensiones anunciadas en Perl (incluidas las capturas con nombre), a fin de garantizar la interoperabilidad con Perl 5, Perl 6 y PCRE, y el creciente número de otros lenguajes que utilizan esta sintaxis extendida. y los autores de ICU y Perl están trabajando juntos para definir una notación común. Sin embargo, ICU adopta principalmente las extensiones adoptadas en las expresiones regulares descritas en el estándar Unicode, ya que ICU sirve como referencia principal en este anexo del estándar Unicode.
Sin embargo, todavía no existe un estándar o estándar técnico para abordar algunos aspectos importantes de las expresiones regulares en un contexto multilingüe, que incluyen:
Para aclarar estos últimos aspectos que faltan, se deberían poder utilizar metacaracteres adicionales para controlar o filtrar las ocurrencias encontradas, o bien un orden estandarizado impuesto en la lista de ocurrencias devueltas. Por lo tanto, los autores de aplicaciones deben estar atentos a estos puntos y asegurarse de leer todas las ocurrencias encontradas y no solo la primera, para poder decidir cuál de las ocurrencias es la más apropiada para una operación determinada.
Las expresiones regulares se usaron originalmente con caracteres ASCII . Muchos motores de expresiones regulares ahora pueden manejar Unicode . En muchos sentidos, el conjunto de caracteres codificados utilizado no hace ninguna diferencia, pero surgen algunos problemas al extender expresiones regulares para Unicode.
Una pregunta es qué formato de representación Unicode interno es compatible. Todos los motores de expresión regular de línea de comando esperan UTF-8 , pero para las bibliotecas, algunos también esperan UTF-8, pero otros esperan un juego codificado UCS-2 solo (o incluso su extensión UTF-16 que también restringe secuencias válidas), o en UCS- 4 solamente (consulte su restricción UTF-32 estandarizada ).
Una segunda pregunta es si se admite todo el rango de valores de una versión de Unicode. Muchos motores solo admiten el plano multilingüe básico , es decir, caracteres codificables de 16 bits. Solo unos pocos motores pueden (desde 2006) manejar los rangos de valores Unicode de 21 bits.
Una tercera pregunta es cómo se extienden las construcciones ASCII a Unicode.
Sin embargo, en la práctica, este no suele ser el caso:
Otra área donde existen variaciones es la interpretación de indicadores de insensibilidad a mayúsculas y minúsculas.
Otra respuesta a Unicode fue la introducción de clases de caracteres para bloques Unicode y propiedades generales de los caracteres Unicode:
Notas:
Hay al menos tres familias de algoritmos que determinan si una cadena coincide con una expresión regular.
El enfoque más antiguo, llamado explícito, se basa en la traducción de la expresión regular en un autómata finito determinista (DFA). La construcción de tal autómata para una expresión regular de tamaño m tiene una complejidad en tamaño y en memoria en O (2 m ) pero se puede ejecutar en una cadena de tamaño n en un tiempo O (n) .
Un enfoque alternativo, llamado implícito, consiste en simular un autómata finito no determinista construyendo cada AFD sobre la marcha y eliminándolo en el siguiente paso. Este enfoque evita la complejidad exponencial del enfoque anterior, pero el tiempo de ejecución aumenta en O (mn) . Estos algoritmos son rápidos pero ciertas funcionalidades como la recaptura de subcadenas y la cuantificación no codiciosa son difíciles de implementar.
El tercer enfoque consiste en comparar el patrón con la cadena de caracteres por separación y evaluación (" retroceso "). Su complejidad algorítmica es exponencial en el peor de los casos, por ejemplo con patrones como (a|aa)*b, pero da buenos resultados en la práctica. Es más flexible y permite un mayor poder expresivo, por ejemplo, simplificando la recaptura de subcadenas.
Algunas implementaciones intentan combinar las cualidades de diferentes enfoques, comenzando la búsqueda con un AFD y luego utilizando la separación y la evaluación cuando sea necesario.