Expresión regular

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar
Secuencia de caracteres que forman un patrón de búsqueda
Destacados azules muestran los resultados del partido del patrón de expresión regular /h[aeiou]+/g (la carta) h seguido de una o más vocales)

Una expresión regular (abreviada como regex o regexp; a veces denominada expresión racional) es una secuencia de caracteres que especifica un patrón de búsqueda en el texto. Por lo general, estos patrones son utilizados por algoritmos de búsqueda de cadenas para "buscar" o "buscar y reemplazar" operaciones en cadenas, o para la validación de entrada. Las técnicas de expresión regular se desarrollan en informática teórica y teoría del lenguaje formal.

El concepto de expresiones regulares comenzó en la década de 1950, cuando el matemático estadounidense Stephen Cole Kleene formalizó el concepto de lenguaje regular. Llegaron a ser de uso común con las utilidades de procesamiento de texto de Unix. Desde la década de 1980 existen diferentes sintaxis para escribir expresiones regulares, una es el estándar POSIX y otra, ampliamente utilizada, es la sintaxis Perl.

Las expresiones regulares se utilizan en motores de búsqueda, en cuadros de diálogo de búsqueda y reemplazo de procesadores de texto y editores de texto, en utilidades de procesamiento de texto como sed y AWK, y en análisis léxico. La mayoría de los lenguajes de programación de propósito general admiten capacidades de expresiones regulares de forma nativa o a través de bibliotecas, incluidos Python, C, C ++, Java, Rust, OCaml y JavaScript.

Historia

Stephen Cole Kleene, quien introdujo el concepto

Las expresiones regulares se originaron en 1951, cuando el matemático Stephen Cole Kleene describió los lenguajes regulares usando su notación matemática llamada eventos regulares. Estos surgieron en la informática teórica, en los subcampos de la teoría de autómatas (modelos de computación) y la descripción y clasificación de lenguajes formales. Otras implementaciones tempranas de coincidencia de patrones incluyen el lenguaje SNOBOL, que no usaba expresiones regulares, sino sus propias construcciones de coincidencia de patrones.

Las expresiones regulares entraron en el uso popular a partir de 1968 en dos usos: coincidencia de patrones en un editor de texto y análisis léxico en un compilador. Una de las primeras apariciones de expresiones regulares en forma de programa fue cuando Ken Thompson incorporó la notación de Kleene en el editor QED como un medio para hacer coincidir patrones en archivos de texto. Para mayor velocidad, Thompson implementó la coincidencia de expresiones regulares mediante la compilación justo a tiempo (JIT) con el código IBM 7094 en el sistema de tiempo compartido compatible, un importante ejemplo temprano de compilación JIT. Más tarde agregó esta capacidad al editor de Unix ed, lo que eventualmente condujo al uso de expresiones regulares en la popular herramienta de búsqueda grep ("grep" es una palabra derivada del comando para la búsqueda de expresiones regulares en el ed editor: g/re/p que significa "Búsqueda global de expresiones regulares e impresión de líneas coincidentes"). Casi al mismo tiempo que Thompson desarrolló QED, un grupo de investigadores, incluido Douglas T. Ross, implementó una herramienta basada en expresiones regulares que se utiliza para el análisis léxico en el diseño de compiladores.

Muchas variaciones de estas formas originales de expresiones regulares se usaron en programas Unix en Bell Labs en la década de 1970, incluidos vi, lex, sed, AWK y expr, y en otros programas como Emacs (que tiene su propio código incompatible). sintaxis y comportamiento). Los Regex fueron posteriormente adoptados por una amplia gama de programas, con estas primeras formas estandarizadas en el estándar POSIX.2 en 1992.

En la década de 1980, las expresiones regulares más complicadas surgieron en Perl, que originalmente derivaba de una biblioteca de expresiones regulares escrita por Henry Spencer (1986), quien más tarde escribió una implementación de Expresiones regulares avanzadas para Tcl. La biblioteca Tcl es una implementación híbrida NFA/DFA con características de rendimiento mejoradas. Los proyectos de software que han adoptado la implementación de expresiones regulares Tcl de Spencer incluyen PostgreSQL. Posteriormente, Perl amplió la biblioteca original de Spencer para agregar muchas funciones nuevas. Parte del esfuerzo en el diseño de Raku (anteriormente llamado Perl 6) es mejorar la integración de expresiones regulares de Perl y aumentar su alcance y capacidades para permitir la definición de gramáticas de expresión de análisis. El resultado es un mini-lenguaje llamado reglas de Raku, que se utilizan para definir la gramática de Raku y proporcionar una herramienta a los programadores en el lenguaje. Estas reglas mantienen las características existentes de las expresiones regulares de Perl 5.x, pero también permiten la definición de estilo BNF de un analizador descendente recursivo a través de subreglas.

El uso de expresiones regulares en estándares de información estructurada para el modelado de documentos y bases de datos comenzó en la década de 1960 y se expandió en la década de 1980 cuando se consolidaron estándares de la industria como ISO SGML (precursor de ANSI "GCA 101-1983"). El núcleo de los estándares del lenguaje de especificación de estructuras consta de expresiones regulares. Su uso es evidente en la sintaxis del grupo de elementos DTD. Antes del uso de expresiones regulares, muchos lenguajes de búsqueda permitían comodines simples, por ejemplo "*" para que coincida con cualquier secuencia de caracteres y "?" para hacer coincidir un solo carácter. Reliquias de esto se pueden encontrar hoy en día en la sintaxis glob para nombres de archivos y en el operador SQL LIKE.

A partir de 1997, Philip Hazel desarrolló PCRE (Expresiones regulares compatibles con Perl), que intenta imitar de cerca la funcionalidad de expresiones regulares de Perl y es utilizado por muchas herramientas modernas, incluidos PHP y Apache HTTP Server.

Hoy en día, las expresiones regulares son ampliamente compatibles con lenguajes de programación, programas de procesamiento de texto (particularmente lexers), editores de texto avanzados y algunos otros programas. El soporte Regex es parte de la biblioteca estándar de muchos lenguajes de programación, incluidos Java y Python, y está integrado en la sintaxis de otros, incluidos Perl y ECMAScript. Las implementaciones de la funcionalidad de expresiones regulares a menudo se denominan motor de expresiones regulares, y hay varias bibliotecas disponibles para su reutilización. A fines de la década de 2010, varias empresas comenzaron a ofrecer implementaciones de hardware, FPGA y GPU de motores regex compatibles con PCRE que son más rápidos en comparación con las implementaciones de CPU.

Patrones

La frase expresiones regulares, o regexes, se usa a menudo para referirse a la sintaxis textual estándar y específica para representar patrones para el texto coincidente, a diferencia de la notación matemática descrita debajo. Cada carácter de una expresión regular (es decir, cada carácter de la cadena que describe su patrón) es un metacarácter que tiene un significado especial o un carácter regular que tiene un significado literal. Por ejemplo, en la expresión regular b., 'b' es un carácter literal que coincide solo con 'b', mientras que '.' es un metacarácter que coincide con todos los caracteres excepto una nueva línea. Por lo tanto, esta expresión regular coincide, por ejemplo, con 'b%', o 'bx', o 'b5'. Juntos, los metacaracteres y los caracteres literales se pueden usar para identificar texto de un patrón determinado o procesar varias instancias del mismo. Las coincidencias de patrones pueden variar desde una igualdad precisa hasta una similitud muy general, controlada por los metacaracteres. Por ejemplo, . es un patrón muy general, [a-z] (hace coincidir todas las letras minúsculas desde 'a' hasta 'z') es menos general y b es un patrón preciso (coincide solo con 'b'). La sintaxis de metacaracteres está diseñada específicamente para representar objetivos prescritos de una manera concisa y flexible para dirigir la automatización del procesamiento de texto de una variedad de datos de entrada, en una forma fácil de escribir usando un teclado ASCII estándar.

Un caso muy simple de una expresión regular en esta sintaxis es ubicar una palabra escrita de dos maneras diferentes en un editor de texto, la expresión regular seriali[sz]e coincide con "serialise& #34; y "serializar". Los caracteres comodín también logran esto, pero están más limitados en lo que pueden modelar, ya que tienen menos metacaracteres y una base de lenguaje simple.

El contexto habitual de los caracteres comodín es incluir nombres similares en una lista de archivos, mientras que las expresiones regulares se emplean generalmente en aplicaciones que coinciden con patrones de cadenas de texto en general. Por ejemplo, la expresión regular ^[ t]+|[ t]+ $ coincide con el exceso de espacios en blanco al principio o al final de una línea. Una expresión regular avanzada que coincide con cualquier número es [+-]?(d +(.d*)?|. d+)([ eE][+-]?d+)?.

Traduciendo la estrella Kleene
()s* significa "cero o más de s")

Un procesador de expresiones regulares traduce una expresión regular en la sintaxis anterior en una representación interna que se puede ejecutar y comparar con una cadena que representa el texto en el que se está buscando. Un enfoque posible es el Thompson' s algoritmo de construcción para construir un autómata finito no determinista (NFA), que luego se convierte en determinista y el autómata finito determinista (DFA) resultante se ejecuta en la cadena de texto de destino para reconocer las subcadenas que coinciden con la expresión regular. La imagen muestra el esquema NFA N(s*) obtenido de la expresión regular s*, donde s denota una expresión regular más simple a su vez, que ya se ha traducido recursivamente a NFA N(s).

Conceptos básicos

Una expresión regular, a menudo llamada patrón, especifica un conjunto de cadenas requeridas para un propósito particular. Una forma sencilla de especificar un conjunto finito de cadenas es listar sus elementos o miembros. Sin embargo, a menudo hay formas más concisas: por ejemplo, el conjunto que contiene las tres cadenas "Handel", "Händel" y "Haendel" se puede especificar mediante el patrón H(ä|ae?)ndel; decimos que este patrón coincide con cada una de las tres cadenas. Sin embargo, puede haber muchas formas de escribir una expresión regular para el mismo conjunto de cadenas: por ejemplo, (Hän|Han|Haen)del también especifica el mismo conjunto de tres cadenas en este ejemplo.

La mayoría de los formalismos proporcionan las siguientes operaciones para construir expresiones regulares.

Booleano "o"
Una barra vertical separa alternativas. Por ejemplo, gray|grey puede igualar "gray" o "grey".
Grupo
Los paréntesis se utilizan para definir el alcance y la precedencia de los operadores (entre otros usos). Por ejemplo, gray|grey y gr(a|e)y son patrones equivalentes que ambos describen el conjunto de "gray" o "grey".
Cuantificación
Un cuantificador después de un elemento (como un token, carácter o grupo) especifica cuántas veces se permite repetir el elemento anterior. Los cuantificadores más comunes son la marca de preguntas ?, el asterisco * (derived from the Kleene star), and the plus sign + (Kleene más).
?La marca de preguntas indica cero o uno sucesos del elemento anterior. Por ejemplo, colou?r coincide con "color" y "color".
*El asterisco indica cero o más sucesos del elemento anterior. Por ejemplo, ab*c partidos "ac", "abc", "abbc", "abbbc", etc.
+El signo más indica uno o más sucesos del elemento anterior. Por ejemplo, ab+c partidos "abc", "abbc", "abbbc", etc., pero no "ac".
{n}El artículo anterior se combina exactamente n veces.
{min,}El artículo anterior se combina min o más veces.
{,max}El artículo anterior se corresponde con max veces.
{min,max}El artículo anterior se combina al menos min veces, pero no más que max veces.
Wildcard

El comodín . coincide con cualquier carácter. Por ejemplo, a.b coincide con cualquier cadena que contenga una "a", y luego cualquier carácter y luego "b"; y a.*b coincide con cualquier cadena que contenga una "a", y luego el carácter "b" en algún momento posterior.

Estas construcciones se pueden combinar para formar expresiones arbitrariamente complejas, al igual que se pueden construir expresiones aritméticas a partir de números y las operaciones +, −, × y ÷.

La sintaxis precisa de las expresiones regulares varía según las herramientas y el contexto; se dan más detalles en § Sintaxis.

Teoría del lenguaje formal

Las expresiones regulares describen lenguajes regulares en la teoría del lenguaje formal. Tienen el mismo poder expresivo que las gramáticas regulares.

Definición formal

Las expresiones regulares constan de constantes, que denotan conjuntos de cadenas, y símbolos de operadores, que denotan operaciones sobre estos conjuntos. La siguiente definición es estándar y se encuentra como tal en la mayoría de los libros de texto sobre teoría del lenguaje formal. Dado un alfabeto finito Σ, se definen las siguientes constantes como expresiones regulares:

  • ()vacío) ∅ denotar el set ∅.
  • ()cuerda vacía) ε denotando el conjunto que contiene sólo la cadena "vacío", que no tiene caracteres en absoluto.
  • ()carácter literal) a en la OPS denotando el conjunto que contiene sólo el carácter a.

Dadas las expresiones regulares R y S, se definen las siguientes operaciones sobre ellas para producir expresiones regulares:

  • ()concatenación) (RS) denota el conjunto de cuerdas que se pueden obtener concatenando una cadena aceptada por R y una cadena aceptada por S (en ese orden). Por ejemplo, que R denote {"ab", "c"} y S denote {"d", "ef"}. Entonces, (RS) denota { "abd", "abef", "cd", "cef"}.
  • ()alternancia) (R|S) denota la unión de conjuntos descritos por R y S. Por ejemplo, si R describe {"ab", "c"} y S describe {"ab", "d", "ef"}, expresión (R|S) describe {"ab", "c", "d", "ef"}.
  • ()Kleene star) (R*) denota el superset más pequeño del conjunto descrito por R que contiene ε y se cierra bajo concatenación de cadenas. Este es el conjunto de todas las cadenas que se pueden hacer concatenando cualquier número finito (incluyendo cero) de cadenas del conjunto descrito por R. Por ejemplo, si R denota {"0", "1"}, (R*) denota el conjunto de todas las cadenas binarias finitas (incluyendo la cadena vacía). Si R denota {"ab", "c"}, (R*) denotes {ε, "ab", "c", "abab", "abc", "cab", "cc", "ababab", "abcab",... }.

Para evitar paréntesis, se supone que la estrella Kleene tiene la prioridad más alta, luego la concatenación y luego la alternancia. Si no hay ambigüedad, se pueden omitir los paréntesis. Por ejemplo, (ab)c se puede escribir como abc, y a|(b(c*)) se puede escribir como a|bc*. Muchos libros de texto usan los símbolos ∪, + o ∨ para la alternancia en lugar de la barra vertical.

Ejemplos:

  • a|b* denota {ε, "a", "b", "bb", "bbb",...}
  • (a|b)* denota el conjunto de todas las cuerdas sin símbolos que no sean "a" y "b", incluyendo la cuerda vacía: {ε, "a", "b", "aa", "ab", "ba", "bb", "aaa",...}
  • ab*(c|ε) denota el conjunto de cuerdas comenzando con "a", luego cero o más "b" y finalmente opcionalmente un "c": {"a", "ac", "ab", "abc", "abb", "abbc",...}
  • (0|(1(01*0)*1))* denota el conjunto de números binarios que son múltiples de 3: { ε, "0", "00", "11", "000", "011", "110", "0000", "0011", "0110", "100", "1100", "1111", "00000",... }

Potencia expresiva y compacidad

La definición formal de las expresiones regulares es mínima a propósito y evita definir ? y +; estas pueden expresarse de la siguiente manera: a+ = aa*, y a? = (a|ε). A veces se agrega el operador de complemento, para dar una expresión regular generalizada; aquí Rc coincide con todas las cadenas sobre Σ* que no coinciden con R. En principio, el operador complemento es redundante, porque no otorga más poder expresivo. Sin embargo, puede hacer que una expresión regular sea mucho más concisa: la eliminación de un solo operador de complemento puede causar una expansión exponencial doble de su longitud.

Las expresiones regulares en este sentido pueden expresar los idiomas regulares, exactamente la clase de idiomas aceptados por automata finita determinista. Sin embargo, hay una diferencia significativa en la compactidad. Algunas clases de idiomas regulares sólo pueden ser descritas por automata finita determinista cuyo tamaño crece exponencialmente en el tamaño de las expresiones regulares equivalentes más cortos. El ejemplo estándar aquí son los idiomas Lk que consiste en todas las cuerdas sobre el alfabeto {a,b} cuyo kT- de la última letra iguala. Por un lado, una expresión regular que describe L4 es dado por ()a▪ ▪ b)Alternativa Alternativa a()a▪ ▪ b)()a▪ ▪ b)()a▪ ▪ b){displaystyle (amid b)}a(amid b)(amid b)(amid b)}.

Generalizar este patrón para Lk da la expresión: ()a▪ ▪ b)Alternativa Alternativa a()a▪ ▪ b)()a▪ ▪ b)⋯ ⋯ ()a▪ ▪ b)⏟ ⏟ k− − 1veces.{displaystyle (amid b)^{*}aunderbrace {(amid b)(amid b)cdots (amid b)} - ¿Qué?

Por otro lado, se sabe que todo autómata finito determinista que acepte el lenguaje Lk debe tener al menos 2k estados. Afortunadamente, existe un mapeo simple de las expresiones regulares a los autómatas finitos no deterministas (NFA) más generales que no conducen a tal aumento de tamaño; por esta razón, los NFA se utilizan a menudo como representaciones alternativas de los lenguajes regulares. Las NFA son una variación simple de las gramáticas de tipo 3 de la jerarquía de Chomsky.

En la dirección opuesta, hay muchos lenguajes que se describen fácilmente mediante un DFA que no se describen fácilmente mediante una expresión regular. Por ejemplo, determinar la validez de un ISBN determinado requiere calcular el módulo de la base entera 11 y puede implementarse fácilmente con un DFA de 11 estados. Sin embargo, una expresión regular para responder al mismo problema de divisibilidad por 11 tiene al menos varios megabytes de longitud.

Dada una expresión regular, el algoritmo de construcción de Thompson calcula un autómata finito no determinista equivalente. El algoritmo de Kleene logra una conversión en la dirección opuesta.

Por último, vale la pena señalar que muchas expresiones "regulares" los motores implementan características que no pueden ser descritas por las expresiones regulares en el sentido de la teoría del lenguaje formal; más bien, implementan regexes. Vea a continuación para obtener más información sobre esto.

Decidir la equivalencia de expresiones regulares

Como se ve en muchos de los ejemplos anteriores, hay más de una forma de construir una expresión regular para lograr los mismos resultados.

Es posible escribir un algoritmo que, para dos expresiones regulares dadas, decida si los lenguajes descritos son iguales; el algoritmo reduce cada expresión a una máquina de estado finito determinista mínima y determina si son isomorfas (equivalentes).

Las leyes algebraicas para las expresiones regulares se pueden obtener utilizando un método de Gischer que se explica mejor con un ejemplo: para comprobar si (X+Y)* y (X* Y*)* indican mismo lenguaje regular, para todas las expresiones regulares X, Y, es necesario y suficiente verificar si las expresiones regulares particulares (a+b)* y (a* b*)* indican el mismo idioma sobre el alfabeto Σ={a,b}. De manera más general, una ecuación E=F entre términos de expresiones regulares con variables se cumple si, y solo si, se cumple su instanciación con diferentes variables reemplazadas por diferentes constantes de símbolos.

Cada expresión regular se puede escribir únicamente en términos de la estrella de Kleene y las uniones de conjuntos. Este es un problema sorprendentemente difícil. Tan simples como son las expresiones regulares, no existe un método para reescribirlas sistemáticamente en alguna forma normal. La falta de axioma en el pasado condujo al problema de la altura de las estrellas. En 1991, Dexter Kozen axiomatizó las expresiones regulares como un álgebra de Kleene, utilizando axiomas ecuacionales y cláusulas de Horn. Ya en 1964, Redko había demostrado que ningún conjunto finito de axiomas puramente ecuacionales puede caracterizar el álgebra de los lenguajes regulares.

Sintaxis

Un patrón de expresión regular coincide con una cadena de destino. El patrón está compuesto por una secuencia de átomos. Un átomo es un punto único dentro del patrón de expresiones regulares que intenta hacer coincidir con la cadena de destino. El átomo más simple es un literal, pero agrupar partes del patrón para que coincida con un átomo requerirá el uso de () como metacaracteres. Los metacaracteres ayudan a formar: átomos; cuantificadores que dicen cuántos átomos (y si es un cuantificador codicioso o no); un carácter OR lógico, que ofrece un conjunto de alternativas, y un carácter NOT lógico, que niega la existencia de un átomo; y retrorreferencias para referirse a átomos anteriores de un patrón completo de átomos. Se hace una coincidencia, no cuando coinciden todos los átomos de la cadena, sino cuando coinciden todos los átomos de patrón en la expresión regular. La idea es hacer que un pequeño patrón de caracteres represente una gran cantidad de posibles cadenas, en lugar de compilar una gran lista de todas las posibilidades literales.

Dependiendo del procesador de expresiones regulares, hay alrededor de catorce metacaracteres, caracteres que pueden o no tener su significado de carácter literal, según el contexto, o si están "escapados", es decir, precedidos por una secuencia de escape, en este caso, la barra invertida . Las expresiones regulares modernas y extendidas de POSIX usan metacaracteres con más frecuencia que su significado literal, por lo que para evitar la "barra diagonal inversa" o el síndrome del palillo inclinado, tiene sentido que un metacarácter escape a un modo literal; pero al principio, tiene más sentido que los cuatro metacaracteres entre paréntesis () y { } sean principalmente literales y "escape" este significado habitual para convertirse en metacaracteres. Los estándares comunes implementan ambos. Los metacaracteres habituales son {}[]()^$.|*+? y . Los caracteres habituales que se convierten en metacaracteres cuando se escapan son dswDSW y N.

Delimitadores

Al ingresar una expresión regular en un lenguaje de programación, pueden representarse como un literal de cadena habitual, por lo tanto, generalmente entre comillas; esto es común en C, Java y Python, por ejemplo, donde la expresión regular re se ingresa como "re". Sin embargo, a menudo se escriben con barras como delimitadores, como en /re/ para la expresión regular re. Esto se origina en ed, donde / es el comando del editor para buscar, y se puede usar una expresión /re/ para especificar un rango de líneas (que coincidan con el patrón), que se puede combinar con otros comandos en cualquier lado, el más famoso g/re/p como en grep ("impresión regular global"), que se incluye en la mayoría de los sistemas operativos basados en Unix, como las distribuciones de Linux. Se utiliza una convención similar en sed, donde s/re/replacement/ proporciona búsqueda y reemplazo y los patrones se pueden unir con una coma para especificar un rango de líneas como en /re1/,/re2/. Esta notación es particularmente conocida debido a su uso en Perl, donde forma parte de la sintaxis distinta de los literales de cadena normales. En algunos casos, como sed y Perl, se pueden usar delimitadores alternativos para evitar la colisión con los contenidos y evitar tener que escapar de las apariciones del carácter delimitador en los contenidos. Por ejemplo, en sed el comando s,/,X, reemplazará un / con un X, usando comas como delimitadores.

Estándares

El estándar IEEE POSIX tiene tres conjuntos de cumplimiento: BRE (Expresiones regulares básicas), ERE (expresiones regulares extendidas) y SRE (expresiones regulares simples). SRE está en desuso, a favor de BRE, ya que ambos brindan compatibilidad con versiones anteriores. La siguiente subsección que cubre las clases de caracteres se aplica tanto a BRE como a ERE.

BRE y ERE trabajan juntos. ERE agrega ?, + y |, y elimina la necesidad de escapar de los metacaracteres () y { }, que son obligatorios en BRE. Además, siempre que se respete la sintaxis estándar de POSIX para expresiones regulares, puede haber, y a menudo hay, sintaxis adicional para servir aplicaciones específicas (pero compatibles con POSIX). Aunque POSIX.2 deja algunos detalles de implementación sin definir, BRE y ERE proporcionan un "estándar" que desde entonces se ha adoptado como la sintaxis predeterminada de muchas herramientas, donde la elección de los modos BRE o ERE suele ser una opción admitida. Por ejemplo, GNU grep tiene las siguientes opciones: "grep -E" para ERE y "grep -G" para BRE (predeterminado) y "grep -P" para expresiones regulares de Perl.

Las expresiones regulares de Perl se han convertido en un estándar de facto, con un conjunto rico y poderoso de expresiones atómicas. Perl no tiene "básico" o "extendido" niveles Al igual que en los ERE POSIX, () y { } se tratan como metacaracteres a menos que se escapen; se sabe que otros metacaracteres son literales o simbólicos según el contexto únicamente. La funcionalidad adicional incluye coincidencia diferida, referencias inversas, grupos de captura con nombre y patrones recursivos.

POSIX básica y extendida

(feminine)

En el estándar POSIX, la sintaxis regular básica (BRE) requiere que los metacaracteres () y { } se designen como () y {}, mientras que la sintaxis regular extendida (ERE) no lo hace.

Metacharacter Descripción
^Coincide con la posición inicial dentro de la cadena. En herramientas lineales, coincide con la posición inicial de cualquier línea.
.Coincide con cualquier personaje único (muchas aplicaciones excluyen las nuevas líneas, y exactamente qué caracteres se consideran nuevas líneas es sabor, codificación de caracteres y plataforma específica, pero es seguro asumir que el carácter de alimentación de línea está incluido). Dentro de las expresiones del soporte POSIX, el personaje del punto coincide con un punto literal. Por ejemplo, a.c partidos "abc", etc., pero [a.c] sólo coincide con "a", ", o "c".
[ ]Una expresión entre corchetes. Coincide con un único personaje que está contenido en los corchetes. Por ejemplo, [abc] fósforos "a", "b", o "c". [a-z] especifica un rango que coincide con cualquier letra minúscula de "a" a "z". Estas formas pueden mezclarse: [abcx-z] cerillas "a", "b", "c", "x", "y", o "z", como lo hace [a-cx-z].

El - carácter es tratado como un carácter literal si es el último o el primero (después del ^, si está presente) carácter dentro de los corchetes: [abc-], [-abc]. Tenga en cuenta que no se permiten escapes de retroceso. El ] el carácter se puede incluir en una expresión entre corchetes si es el primero (después del ^) carácter: []abc].

[^ ]Coincide con un único personaje que no está contenido en los corchetes. Por ejemplo, [^abc] coincide con cualquier personaje que no sea "a", "b", o "c". [^a-z] coincide con cualquier personaje único que no es una letra minúscula de "a" a "z". Del mismo modo, caracteres literales y rangos pueden ser mezclados.
$Coincide con la posición final de la cadena o la posición justo antes de una nueva línea final de cadena. En herramientas de línea, coincide con la posición final de cualquier línea.
()Define una subexpresión marcada. La cadena concordada dentro de los paréntesis se puede recordar más tarde (ver la siguiente entrada, n). Una subexpresión marcada también se llama un bloque o grupo de captura. Modo BRE requiere ().
nCoincide con lo que nth marcado subexpresión coincide, donde n es un dígito de 1 a 9. Esta construcción se define vagamente en el estándar POSIX.2. Algunas herramientas permiten hacer referencia a más de nueve grupos de captura. También conocido como una referencia. solo se admiten referencias en modo BRE
*Coincide con el elemento anterior cero o más veces. Por ejemplo, ab*c partidos "ac", "abc", "abbbc", etc. [xyz]* cerillas "", "x", "y", "z", "zx", "zyx", "xyzzy", etc. (ab)* fósforos "", "ab", "abab", "ababab", etcétera.
{m,n}Coincide con el elemento anterior al menos m y no más que n veces. Por ejemplo, a{3,5} sólo coincide con "aaaa", "aaaa", y "aaaaaa". Esto no se encuentra en algunas instancias antiguas de regexes. Modo BRE requiere {m,n}.

Ejemplos:

  • .at coincide con cualquier cadena de tres caracteres que termina con "at", incluyendo "hat", "cat", "bat", "4at", "#at" y " at" (comenzando con un espacio).
  • [hc]at partidos "hat" y "cat".
  • [^b]at coincide con todas las cadenas .at excepto "bat".
  • [^hc]at coincide con todas las cadenas .at más que "hat" y "cat".
  • ^[hc]at coincide con "hat" y "cat", pero sólo al principio de la cuerda o línea.
  • [hc]at$ coincide con "hat" y "cat", pero sólo al final de la cadena o línea.
  • [.] coincide con cualquier personaje único rodeado de "[" y "]" desde que se escapan los corchetes, por ejemplo: "[a]", "[b]", "[@]", "[]", y "[ ]" (pantalla del techo).
  • s.* fósforos seguidos por cero o más caracteres, por ejemplo: "s", "sierra", "s3w96.7", y "s6#h%(Conferencial n mQ".

POSIX extendida

(feminine)

El significado de los metacaracteres escapados con una barra invertida se invierte para algunos caracteres en la sintaxis de la expresión regular extendida POSIX (ERE). Con esta sintaxis, una barra invertida hace que el metacarácter se trate como un carácter literal. Entonces, por ejemplo, () ahora es () y { } ahora es { }. Además, se elimina la compatibilidad con las referencias inversas n y se agregan los siguientes metacaracteres:

Metacharacter Descripción
?Coincide con el elemento anterior cero o una vez. Por ejemplo, ab?c coincide con "ac" o "abc".
+Coincide con el elemento anterior una o más veces. Por ejemplo, ab+c partidos "abc", "abbc", "abbbc", etc., pero no "ac".
|El operador de elección (también conocido como alternancia o unión) coincide con la expresión antes o la expresión después del operador. Por ejemplo, abc|def partidos "abc" o "def".

Ejemplos:

  • [hc]?at fósforos "at", "hat", y "cat".
  • [hc]*at "at", "hat", "cat", "hhat", "chat", "hcat", "cchchat", etc.
  • [hc]+at partidos "hat", "cat", "hhat", "chat", "hcat", "cchchat", etc., pero no "at".
  • cat|dog partidos "cat" o "dog".

Las expresiones regulares extendidas de POSIX a menudo se pueden usar con las utilidades modernas de Unix al incluir el indicador de línea de comando -E.

Clases de personajes

La clase de carácter es el concepto de expresiones regulares más básico después de una coincidencia literal. Hace que una pequeña secuencia de caracteres coincida con un conjunto más grande de caracteres. Por ejemplo, [A-Z] podría representar cualquier letra mayúscula del alfabeto inglés y d podría significar cualquier dígito. Las clases de caracteres se aplican a ambos niveles POSIX.

Al especificar un rango de caracteres, como [a-Z] (es decir, minúsculas a a mayúsculas Z), la configuración regional de la computadora determina el contenido por el orden numérico de la codificación de caracteres. Podrían almacenar dígitos en esa secuencia, o el orden podría ser abc…zABC…Z, o aAbBcC…zZ. Entonces, el estándar POSIX define una clase de carácter, que será conocida por el procesador de expresiones regulares instalado. Esas definiciones se encuentran en la siguiente tabla:

Descripción POSIXPerl/TclVimJavaASCII
ASCII caracteres p{ASCII}[x00-x7F]
Carácteres alfabético [:alnum:]p{Alnum}[A-Za-z0-9]
Personajes alfabéricos más "_" www[A-Za-z0-9_]
No palabras caracteres WWW[^A-Za-z0-9_]
Carácteres alfabéticos [:alpha:]ap{Alpha}[A-Za-z]
Espacio y ficha [:blank:]sp{Blank}[ t]
Límites de palabras bb(?<=W)(?=w)|(?<=w)(?=W)
Límites no palabras B(?<=W)(?=W)|(?<=w)(?=w)
Control de caracteres [:cntrl:]p{Cntrl}[x00-x1Fx7F]
Digits [:digit:]ddp{Digit} o d[0-9]
No dígitos DDD[^0-9]
Personajes visibles [:graph:]p{Graph}[x21-x7E]
Cartas minúsculas [:lower:]lp{Lower}[a-z]
Personajes visibles y el carácter espacial [:print:]pp{Print}[x20-x7E]
Carácteres de puntuación [:punct:]p{Punct}[][!"#$%&'()*+,./:;?@^_`{|}~-]
caracteres del espacio blanco [:space:]s_sp{Space} o s[ trnvf]
caracteres no blancos SSS[^ trnvf]
Cartas mayúsculas [:upper:]up{Upper}[A-Z]
dígitos hexadecimales [:xdigit:]xp{XDigit}[A-Fa-f0-9]

Las clases de caracteres POSIX solo se pueden usar dentro de expresiones entre paréntesis. Por ejemplo, [[:superior:]ab] coincide con las letras mayúsculas y minúsculas " un" y "b".

Una clase adicional que no es POSIX que algunas herramientas entienden es [:word:], que generalmente se define como [:alnum:] más guión bajo. Esto refleja el hecho de que en muchos lenguajes de programación estos son los caracteres que pueden usarse en los identificadores. El editor Vim distingue aún más las clases word y word-head (utilizando la notación w y h) ya que en muchos lenguajes de programación los caracteres que pueden comenzar un identificador no son los mismos que los que pueden aparecer en otras posiciones: los números generalmente se excluyen, por lo que un identificador se vería como hw* o [ [:alfa:]_][[:alnum:]_ ]* en notación POSIX.

Tenga en cuenta que lo que los estándares de expresiones regulares POSIX llaman clases de caracteres se denominan comúnmente clases de caracteres POSIX en otras versiones de expresiones regulares que las admiten. Con la mayoría de los otros tipos de expresiones regulares, el término clase de caracteres se usa para describir lo que POSIX llama expresiones de paréntesis.

Perl y PCRE

Debido a su poder expresivo y (relativa) facilidad de lectura, muchas otras utilidades y lenguajes de programación han adoptado una sintaxis similar a la de Perl, por ejemplo, Java, JavaScript, Julia, Python, Ruby, Qt, Microsoft. 39; s.NET Framework y esquema XML. Algunos lenguajes y herramientas, como Boost y PHP, admiten varios tipos de expresiones regulares. Las implementaciones de expresiones regulares derivadas de Perl no son idénticas y generalmente implementan un subconjunto de funciones que se encuentran en Perl 5.0, lanzado en 1994. Perl a veces incorpora funciones que inicialmente se encuentran en otros idiomas. Por ejemplo, Perl 5.10 implementa extensiones sintácticas desarrolladas originalmente en PCRE y Python.

Coincidencia perezosa

En Python y algunas otras implementaciones (por ejemplo, Java), los tres cuantificadores comunes (*, + y ?) son codiciosos por defecto porque coinciden con tantos caracteres como sea posible. La expresión regular ".+" (incluidas las comillas dobles) aplicada a la cadena

"Ganymede", continuó, "es la luna más grande del Sistema Solar".

coincide con toda la línea (porque la línea completa comienza y termina con comillas dobles) en lugar de coincidir solo con la primera parte, "Ganimedes,". Sin embargo, los cuantificadores antes mencionados pueden hacerse perezosos o mínimos o renuentes, haciendo coincidir la menor cantidad de caracteres posible, agregando un signo de interrogación: ".+?" solo coincide con "Ganímedes,".

Coincidencia posesiva

En Java y Python 3.11+, los cuantificadores se pueden convertir en posesivos agregando un signo más, lo que desactiva la marcha atrás (en un motor de retroceso), incluso si hacerlo permitiría que la coincidencia general tenga éxito: mientras que la expresión regular ".*" se aplicó a la cadena

"Ganymede", continuó, "es la luna más grande del Sistema Solar".

coincide con toda la línea, la expresión regular ".*+" no coincide en absoluto, porque .*+ consume toda la entrada, incluido el " final. Por lo tanto, los cuantificadores posesivos son más útiles con clases de caracteres negados, p. "[^"]*+", que coincide con "Ganymede," cuando se aplica a la misma cadena.

Otra extensión común que cumple la misma función es la agrupación atómica, que desactiva el retroceso para un grupo entre paréntesis. La sintaxis típica es (?>group). Por ejemplo, mientras que ^(wi|w)i$ coincide con wi y wii, ^(?>wi|w)i$ solo coincide con wii porque el motor tiene prohibido retroceder y por lo tanto, no puede intentar establecer el grupo en "w" después de hacer coincidir "wi".

Los cuantificadores posesivos son más fáciles de implementar que los cuantificadores codiciosos y perezosos y, por lo general, son más eficientes en tiempo de ejecución.

Patrones para idiomas no regulares

Muchas funciones que se encuentran en prácticamente todas las bibliotecas de expresiones regulares modernas brindan un poder expresivo que supera a los lenguajes regulares. Por ejemplo, muchas implementaciones permiten agrupar subexpresiones con paréntesis y recordar el valor que coinciden en la misma expresión (referencias). Esto significa que, entre otras cosas, un patrón puede coincidir con cadenas de palabras repetidas como "papá" o "WikiWiki", llamados cuadrados en la teoría del lenguaje formal. El patrón para estas cadenas es (.+)1.

El lenguaje de los cuadrados no es regular, ni está libre de contexto, debido al lema de bombeo. Sin embargo, la coincidencia de patrones con un número ilimitado de referencias inversas, como lo admiten numerosas herramientas modernas, sigue siendo sensible al contexto. El problema general de hacer coincidir cualquier número de referencias inversas es NP-completo, que crece exponencialmente según el número de grupos de referencias inversas utilizados.

Sin embargo, muchas herramientas, bibliotecas y motores que brindan tales construcciones todavía usan el término expresión regular para sus patrones. Esto ha llevado a una nomenclatura en la que el término expresión regular tiene diferentes significados en la teoría del lenguaje formal y la coincidencia de patrones. Por esta razón, algunas personas han usado el término regex, regexp o simplemente patrón para describir este último. Larry Wall, autor del lenguaje de programación Perl, escribe en un ensayo sobre el diseño de Raku:

"Expresiones regulares" [...] sólo están marginalmente relacionadas con expresiones regulares reales. Sin embargo, el término ha crecido con las capacidades de nuestros motores de juego de patrones, así que no voy a tratar de luchar contra la necesidad lingüística aquí. Sin embargo, generalmente los llamaré "regexes" (o "regexen", cuando estoy de humor anglosajón).

Afirmaciones

AssertionLookbehindMira.
Positivo (?.patrón) (?=patrón)
Negativo (?¡Atención!patrón) (?!patrón)
Detrás de la mirada y afirmaciones de la cabeza
en Perl expresiones regulares

Otras características que no se encuentran en la descripción de lenguajes regulares incluyen aserciones. Estos incluyen los ubicuos ^ y $, utilizados desde al menos 1970, así como algunas extensiones más sofisticadas como lookaround que apareció en 1994. Lookarounds define el entorno de una coincidencia y no se derrama en la coincidencia en sí, una característica que solo es relevante para el caso de uso de la búsqueda de cadenas. Algunos de ellos se pueden simular en un lenguaje regular al tratar el entorno como parte del lenguaje también.

Las aserciones de anticipación (?=…) y (?!…) han sido certificadas desde al menos 1994, comenzando con Perl 5. Las aserciones (?<=…) y (?<!…) están certificadas desde 1997 en una confirmación de Ilya Zakharevich para Perl 5.005.

Implementaciones y tiempos de ejecución

Hay al menos tres algoritmos diferentes que deciden si una expresión regular dada coincide con una cadena y cómo.

El más antiguo y rápido se basa en un resultado de la teoría del lenguaje formal que permite que cada autómata finito no determinista (NFA) se transforme en un autómata finito determinista (DFA). El DFA puede construirse explícitamente y luego ejecutarse en la cadena de entrada resultante, un símbolo a la vez. Construir el DFA para una expresión regular de tamaño m tiene un costo de tiempo y memoria de O(2m), pero se puede ejecutar en una cadena de tamaño n en tiempo O(n). Tenga en cuenta que el tamaño de la expresión es el tamaño después de que se hayan expandido las abreviaturas, como los cuantificadores numéricos.

Un enfoque alternativo es simular el NFA directamente, esencialmente creando cada estado de DFA a pedido y luego descartándolo en el siguiente paso. Esto mantiene el DFA implícito y evita el costo de construcción exponencial, pero el costo de funcionamiento aumenta a O(mn). El enfoque explícito se denomina algoritmo DFA y el enfoque implícito, algoritmo NFA. Agregar almacenamiento en caché al algoritmo NFA a menudo se denomina "DFA perezoso" algoritmo, o simplemente el algoritmo DFA sin hacer una distinción. Estos algoritmos son rápidos, pero usarlos para recuperar subexpresiones agrupadas, cuantificación diferida y características similares es complicado. Las implementaciones modernas incluyen la familia re1-re2-sregex basada en el código de Cox.

El tercer algoritmo es hacer coincidir el patrón con la cadena de entrada retrocediendo. Este algoritmo se denomina comúnmente NFA, pero esta terminología puede resultar confusa. Su tiempo de ejecución puede ser exponencial, que las implementaciones simples exhiben cuando se comparan con expresiones como (a|aa)*b que contienen ambas alternancias y la cuantificación ilimitada y fuerzan al algoritmo a considerar un número exponencialmente creciente de subcasos. Este comportamiento puede causar un problema de seguridad llamado Denegación de servicio de expresiones regulares (ReDoS).

Aunque las implementaciones de retroceso solo brindan una garantía exponencial en el peor de los casos, brindan mucha más flexibilidad y poder expresivo. Por ejemplo, cualquier implementación que permita el uso de referencias hacia atrás, o implemente las diversas extensiones introducidas por Perl, debe incluir algún tipo de retroceso. Algunas implementaciones intentan proporcionar lo mejor de ambos algoritmos ejecutando primero un algoritmo DFA rápido y volviendo a un algoritmo de retroceso potencialmente más lento solo cuando se encuentra una referencia inversa durante la coincidencia. GNU grep (y el gnulib DFA subyacente) utiliza una estrategia de este tipo.

Los algoritmos de tiempo de ejecución sublineales se lograron mediante algoritmos basados en Boyer-Moore (BM) y técnicas de optimización de DFA relacionadas, como el escaneo inverso. GNU grep, que admite una amplia variedad de sintaxis y extensiones POSIX, usa BM para un filtrado previo de primer paso y luego usa un DFA implícito. Wu agrep, que implementa la coincidencia aproximada, combina el prefiltrado en el DFA en BDM (coincidencia DAWG hacia atrás). El BNDM de NR-grep amplía la técnica BDM con el paralelismo de nivel de bit Shift-Or.

Existen algunas alternativas teóricas al retroceso para las referencias, y sus "exponentes" son tamer en que sólo están relacionados con el número de referencias, una propiedad fija de algunos idiomas regexp como POSIX. Un método ingenuo que duplica un NFA no retrocedente para cada nota de referencia tiene una complejidad O()n2k+2){displaystyle {mathrm}(n^{2k+2}} tiempo y tiempo O()n2k+1){displaystyle {mathrm}(n^{2k+1})} espacio para un pajar de longitud n y k backreferencias en el RegExp. Un trabajo teórico muy reciente basado en la memoria automata da un límite más ajustado basado en nodos variables "activos" utilizados, y una posibilidad polinómica para algunos reexps backreferenced.

Unicódigo

En términos teóricos, cualquier conjunto de tokens puede coincidir con expresiones regulares siempre que esté predefinido. En términos de implementaciones históricas, las expresiones regulares se escribieron originalmente para usar caracteres ASCII como su conjunto de tokens, aunque las bibliotecas de expresiones regulares han admitido muchos otros conjuntos de caracteres. Muchos motores de expresiones regulares modernos ofrecen al menos cierto soporte para Unicode. En la mayoría de los aspectos, no importa cuál sea el conjunto de caracteres, pero surgen algunos problemas al extender las expresiones regulares para admitir Unicode.

  • Codificación apoyada. Algunas bibliotecas regex esperan trabajar en alguna codificación particular en lugar de en caracteres abstractos Unicode. Muchos de ellos requieren la codificación UTF-8, mientras que otros pueden esperar UTF-16, o UTF-32. En contraste, Perl y Java son agnósticos en codificaciones, en lugar de operar en caracteres decodificados internamente.
  • Gama Unicode compatible. Muchos motores regex solo soportan el Plano Multilingüe Básico, es decir, los caracteres que se pueden codificar con sólo 16 bits. Actualmente (a partir de 2016) sólo algunos motores regex (por ejemplo, Perl's y Java's) pueden manejar el rango Unicode completo de 21 bits.
  • Ampliación de construcciones orientadas a ASCII a Unicode. Por ejemplo, en las implementaciones basadas en ASCII, los rangos de caracteres de la forma [x-y] son válidos dondequiera x y Sí. tienen puntos de código en el rango [0x00,0x7F] y codepoint(x) ≤ codigo(Sí.). La extensión natural de tales rangos de caracteres a Unicode simplemente cambiaría el requisito de que los puntos finales se encuentran en [0x00,0x7F] al requisito de que se encuentran en [0x0000,0x10FF]. Sin embargo, en la práctica esto a menudo no es el caso. Algunas implementaciones, como la de gawk, no permiten que los rangos de caracteres crucen bloques Unicode. Un rango como [0x61,0x7F] es válido ya que ambos puntos finales caen dentro del bloque latino básico, como es [0x0530,0x0560] ya que ambos puntos finales caen dentro del bloque armenio, pero un rango como [0x0061,0x0532] es inválido ya que incluye múltiples bloques Unicode. Otros motores, como el del editor Vim, permiten el cruce de bloques pero los valores de carácter no deben ser más de 256 separados.
  • Caso de insensibilidad. Algunas banderas de insensibilidad de caso afectan sólo a los personajes de ASCII. Otras banderas afectan a todos los personajes. Algunos motores tienen dos banderas diferentes, una para ASCII, la otra para Unicode. Exactamente qué caracteres pertenecen a las clases POSIX también varía.
  • Cousins of case insensitivity. Como ASCII tiene distinción de caso, la insensibilidad de caso se convirtió en una característica lógica en la búsqueda de texto. Unicode introdujo scripts alfabéticos sin caso como Devanagari. Para ello, la sensibilidad de caso no es aplicable. Para scripts como chino, otra distinción parece lógica: entre tradicionales y simplificados. En los guiones árabes se puede desear la insensibilidad a la posición inicial, medial, final y aislada. En japonés, la insensibilidad entre hiragana y katakana es a veces útil.
  • Normalización. Unicode combina caracteres. Al igual que los escritores antiguos, caracteres de base simple (espacios blancos, caracteres de puntuación, símbolos, dígitos o letras) pueden ser seguidos por uno o más símbolos no espacíficos (generalmente diacríticos, como notas de acento modificando letras) para formar un único carácter imprimible; pero Unicode también proporciona un conjunto limitado de caracteres precomposados, es decir, caracteres que ya incluyen uno o más caracteres que combinan. Una secuencia de un personaje base + combinando caracteres debe ser igualada con el carácter único precompuesta idéntico (sólo algunas de estas secuencias que combinan pueden ser precompuestas en un único carácter Unicode, pero infinitamente muchas otras secuencias que combinan son posibles en Unicode, y necesarias para varios idiomas, utilizando uno o más caracteres que combinan después de un personaje base inicial; estas secuencias que combinan secuencias podrá incluir un personaje base o combinar caracteres parcialmente precomposados, pero no necesariamente en orden canónico y no necesariamente utilizar las precomposiciones canónicas). El proceso de estandarización de secuencias de un personaje base + combinando caracteres descomponiendo estos cónicamente equivalente secuencias, antes de reordenarlas en orden canónico (y opcionalmente recomponer algunos combinar caracteres en el personaje principal base) se llama normalización.
  • Nuevos códigos de control. Unicode introducido entre otros, byte order marks and text direction markers. Estos códigos podrían tener que tratarse de una manera especial.
  • Introducción de clases de caracteres para bloques Unicode, scripts y numerosas propiedades de carácter. Las propiedades del bloque son mucho menos útiles que las propiedades del script, porque un bloque puede tener puntos de código de varios scripts diferentes, y un script puede tener puntos de código de varios bloques diferentes. En Perl y en java.util.regex biblioteca, propiedades del formulario p{InX} o p{Block=X} personajes de partido en bloque X y P{InX} o P{Block=X} coincide con los puntos de código no en ese bloque. Análogamente, p{Armenian}, p{IsArmenian}, o p{Script=Armenian} coincide con cualquier personaje del guión armenio. En general, p{X} coincide con cualquier personaje con la propiedad binaria X o la categoría general X. Por ejemplo, p{Lu}, p{Uppercase_Letter}, o p{GC=Lu} coincide con cualquier carta superior. Propiedades binarias que son no categorías generales p{White_Space}, p{Alphabetic}, p{Math}, y p{Dash}. Ejemplos de propiedades no binarias son p{Bidi_Class=Right_to_Left}, p{Word_Break=A_Letter}, y p{Numeric_Value=10}.

Usos

Una lista negra en Wikipedia que utiliza expresiones regulares para identificar títulos malos

Las expresiones regulares son útiles en una amplia variedad de tareas de procesamiento de texto y, en general, en el procesamiento de cadenas, donde los datos no necesitan ser textuales. Las aplicaciones comunes incluyen la validación de datos, el raspado de datos (especialmente el raspado web), la disputa de datos, el análisis simple, la producción de sistemas de resaltado de sintaxis y muchas otras tareas.

Si bien las expresiones regulares serían útiles en los motores de búsqueda de Internet, procesarlas en toda la base de datos podría consumir recursos informáticos excesivos según la complejidad y el diseño de la expresión regular. Aunque en muchos casos los administradores del sistema pueden ejecutar internamente consultas basadas en expresiones regulares, la mayoría de los motores de búsqueda no ofrecen compatibilidad con expresiones regulares al público. Las excepciones notables incluyen Google Code Search y Exalead. Sin embargo, Google Code Search se cerró en enero de 2012.

Ejemplos

Las reglas de sintaxis específicas varían según la implementación específica, el lenguaje de programación o la biblioteca en uso. Además, la funcionalidad de las implementaciones de expresiones regulares puede variar entre versiones.

Debido a que las expresiones regulares pueden ser difíciles de explicar y comprender sin ejemplos, los sitios web interactivos para probar expresiones regulares son un recurso útil para aprender expresiones regulares mediante la experimentación. Esta sección proporciona una descripción básica de algunas de las propiedades de las expresiones regulares a modo de ilustración.

En los ejemplos se utilizan las siguientes convenciones.

metacharacter(s); la columna metacharacters especifica la sintaxis regex demostrada
=~ m/; indica un regex partido en Perl
=~ s///; indica un regex sustitución en Perl

También vale la pena señalar que estas expresiones regulares son todas de sintaxis similar a Perl. Las expresiones regulares POSIX estándar son diferentes.

A menos que se indique lo contrario, los siguientes ejemplos se ajustan al lenguaje de programación Perl, versión 5.8.8, 31 de enero de 2006. Esto significa que otras implementaciones pueden carecer de soporte para algunas partes de la sintaxis que se muestra aquí (por ejemplo, expresión regular básica o extendida, () frente a (), o falta de d en lugar de POSIX [:digit:]).

La sintaxis y las convenciones utilizadas en estos ejemplos también coinciden con las de otros entornos de programación.

Meta-character(s) Descripción Ejemplo
.Normalmente coincide con cualquier personaje excepto una nueva línea.
Entre corchetes el punto es literal.
$string1 = "Hola Mundo";si ()$string1 = m/) {} impresión "$string1 tiene longitud "= 5.n";}

Producto:

Hola Mundo tiene longitud 5.
()Grupo una serie de elementos de patrón a un solo elemento.
Cuando coincida con un patrón dentro de los paréntesis, puede utilizar cualquiera de $1, $2,... más tarde para referirse al patrón previamente emparejado. Algunas implementaciones pueden usar una notación de retroceso en su lugar, como 1, 2.
$string1 = "Hola Mundo";si ()$string1 = m/(H.).(o.)/) {} impresión "Acordamos con 1 y 2 dólares".;}

Producto:

Concordamos con 'Hel' y 'o W'.
+Coincide con el elemento patrón anterior una o más veces.
$string1 = "Hola Mundo";si ()$string1 = m/l+/) {} impresión "Hay una o más carta consecutiva "l" en $string1.n";}

Producto:

Hay una o más carta consecutiva "l" en Hello World.
?Coincide con el elemento de patrón anterior cero o una vez.
$string1 = "Hola Mundo";si ()$string1 = m/H.?e/) {} impresión "Hay un 'H' y un 'e' separados por "; impresión "0-1 caracteres (por ejemplo, Él Hue Hee).n";}

Producto:

Hay un 'H' y un 'e' separados por 0-1 caracteres (por ejemplo, Él Hue Hee).
?Modifica el *, +, ? o {M,N}'d regex que viene antes para coincidir tan pocas veces como sea posible.
$string1 = "Hola Mundo";si ()$string1 = m/(l.+?o)/) {} impresión "El partido no-verde con 'l' seguido por uno o "; impresión "más caracteres es 'llo' en lugar de 'llo Wo'.;}

Producto:

El partido no-verde con 'l' seguido por uno o más caracteres es 'llo' en lugar de 'llo Wo'.
*Coincide con el elemento patrón anterior cero o más veces.
$string1 = "Hola Mundo";si ()$string1 = m/el*o/) {} impresión "Hay un 'e' seguido por cero a muchos "; impresión "'I' seguido por 'o' (por ejemplo, eo, elo, ello, elllo).n";}

Producto:

Hay un 'e' seguido por cero a muchos 'l' seguido por 'o' (por ejemplo, eo, elo, ello, elllo).
{M,N}Denota el mínimo M y el recuento máximo N.
N se puede omitir y M puede ser 0: {M} fósforos "exactamente" M veces; {M,} fósforos "al menos" M veces; {0,N} fósforos "en la mayoría" N veces.
x* y+ z? por lo tanto equivale a x{0,} y{1,} z{0,1}.
$string1 = "Hola Mundo";si ()$string1 = m/l{1,2}/) {} impresión "Existe una subestring con al menos 1 "; impresión "y al menos 2 estoy en $string1n";}

Producto:

Existe una subestring con al menos 1 y al menos 2 l's en Hello World
[…]Denota un conjunto de posibles partidos de carácter.
$string1 = "Hola Mundo";si ()$string1 = m/[aeiou]+/) {} impresión "$string1 contiene una o más vocales.n";}

Producto:

Hola Mundo contiene una o más vocales.
|Separa posibilidades alternativas.
$string1 = "Hola Mundo";si ()$string1 = m/(Hello sufrimientoHi habitPogo)/) {} impresión "$string1 contiene al menos una de Hola, Hola o Pogo.";}

Producto:

Hola Mundo contiene al menos uno de Hola, Hola o Pogo.
bCoincide con un límite de cero ancho entre un personaje de clase palabra (ver siguiente) y un personaje de clase no palabra o un borde; igual que

(^w|w$|Ww|wW).

$string1 = "Hola Mundo";si ()$string1 = m/llob/) {} impresión "Hay una palabra que termina con 'llo'.;}

Producto:

Hay una palabra que termina con 'llo'.
wCoincide con un carácter alfanumérico, incluyendo "_";
igual que [A-Za-z0-9_] en ASCII, y
[p{Alphabetic}p{GC=Mark}p{GC=Decimal_Number}p{GC=Connector_Punctuation}]

en Unicode, donde el Alphabetic la propiedad contiene más que letras latinas, y Decimal_Number propiedad contiene más que dígitos árabes.

$string1 = "Hola Mundo";si ()$string1 = m/w/) {} impresión "Hay al menos un alfanumérico"; impresión "Caracter en $string1 (A-Z, a-z, 0-9, _).n";}

Producto:

Hay al menos un personaje alfanumérico en Hello World (A-Z, a-z, 0-9, _).
WCoincide con un no- carácter alfanumérico, excluyendo "_";
igual que [^A-Za-z0-9_] en ASCII, y
[^p{Alphabetic}p{GC=Mark}p{GC=Decimal_Number}p{GC=Connector_Punctuation}]

en Unicode.

$string1 = "Hola Mundo";si ()$string1 = m/W/) {} impresión "El espacio entre Hola y "; impresión El mundo no es alfanumérico.;}

Producto:

El espacio entre Hello y World no es alfanumérico.
sCoincide con un personaje del espacio blanco,
que en ASCII son tab, alimentación de línea, alimentación de forma, retorno de carro y espacio;
en Unicode, también coincide con no-espacios de descanso, la siguiente línea, y la variable-espacios anchos (entre otros).
$string1 = "Hola Mundo";si ()$string1 = m/s.) {} impresión "En $string1 hay caracteres blancos TWO, que pueden"; impresión "Sé separado por otros personajes.";}

Producto:

En Hello World hay caracteres de espacio blanco TWO, que pueden ser separados por otros personajes.
SCoincide con cualquier cosa pero un espacio blanco.
$string1 = "Hola Mundo";si ()$string1 = m/S.*S/) {} impresión "En $string1 hay caracteres no blancos TWO, que"; impresión "puede ser separado por otros personajes.;}

Producto:

En Hello World hay caracteres no blancos TWO, que pueden ser separados por otros personajes.
dCoincide con un dígito;
igual que [0-9] in ASCII;
en Unicode, igual que el p{Digit} o p{GC=Decimal_Number} propiedad, que en sí misma p{Numeric_Type=Decimal} propiedad.
$string1 = "99 botellas de cerveza en la pared".;si ()$string1 = m/(d+)/) {} impresión "$1 es el primer número en '$string1'n";}

Producto:

99 es el primer número en '99 botellas de cerveza en la pared. '
DCoincide con un no dígito;
igual que [^0-9] en ASCII o P{Digit} en Unicode.
$string1 = "Hola Mundo";si ()$string1 = m/D/) {} impresión "Hay al menos un personaje en $string1"; impresión Eso no es un dígito.;}

Producto:

Hay al menos un personaje en Hello World Eso no es un dígito.
^Coincide con el comienzo de una línea o cadena.
$string1 = "Hola Mundo";si ()$string1 = m/^He/) {} impresión "$string1 comienza con los personajes 'He'.n";}

Producto:

Hola Mundo comienza con los personajes 'Él'.
$Coincide con el final de una línea o cadena.
$string1 = "Hola Mundo";si ()$string1 = m/rld$/) {} impresión "$string1 es una línea o cadena "; impresión "que termina con 'rld'.;}

Producto:

Hola Mundo es una línea o cadena que termina con 'rld'.
ACoincide con el comienzo de una cadena (pero no con una línea interna).
$string1 = "HolanWorld";si ()$string1 = m/AH/) {} impresión "$string1 es una cuerda"; impresión "que empieza con 'H'.;}

Producto:

Hola.Mundo es una cuerda que comienza con 'H'.
zCoincide con el final de una cadena (pero no con una línea interna).
$string1 = "HolanWorld";si ()$string1 = m/dnz/) {} impresión "$string1 es una cuerda"; impresión "que termina con 'd 'n'.;}

Producto:

Hola.Mundo es una cuerda que termina con 'dn'.
[^…]Coincide con cada personaje excepto los que están dentro de los corchetes.
$string1 = "Hola Mundo";si ()$string1 = m/[^abc]/) {} impresión "$string1 contiene un personaje aparte de "; impresión "a, b, and c.n";}

Producto:

Hola Mundo contiene un personaje que no sea a, b, y c.

Inducción

Las expresiones regulares a menudo se pueden crear ("inducidas" o "aprendidas") en función de un conjunto de cadenas de ejemplo. Esto se conoce como la inducción de lenguajes regulares y es parte del problema general de la inducción gramatical en la teoría del aprendizaje computacional. Formalmente, dados ejemplos de cadenas en un lenguaje regular, y quizás también dados ejemplos de cadenas no en ese lenguaje regular, es posible inducir una gramática para el lenguaje, es decir, una expresión regular que genera ese idioma. No todos los idiomas regulares se pueden inducir de esta manera (ver identificación de idiomas en el límite), pero muchos sí. Por ejemplo, el conjunto de ejemplos {1, 10, 100} y el conjunto negativo (de contraejemplos) {11, 1001, 101, 0} pueden usarse para inducir la expresión regular 1⋅0* (1 seguido de cero o más 0).

Contenido relacionado

Airbus a319

El Airbus A319 es un miembro de la familia Airbus A320 de aviones comerciales bimotor de pasajeros de corto a mediano alcance, de fuselaje estrecho...

Linterna mágica

Contador Geiger

Más resultados...
Tamaño del texto:
undoredo
format_boldformat_italicformat_underlinedstrikethrough_ssuperscriptsubscriptlink
save