Aprenda a utilizar y sacar el máximo partido a las expresiones regulares
Este tutorial completo de expresiones regulares le enseña todo lo que necesita saber para poder elaborar potentes regex que ahorran tiempo (y dinero). Comienza con los conceptos más básicos, para que puedas seguir este tutorial incluso si no sabes nada todavía sobre expresiones regulares.
El tutorial no se detiene ahí. También explica cómo funciona un motor de expresiones regulares por dentro y te avisa de las consecuencias. Esto le ayuda a entender rápidamente por qué una expresión regular en particular no hace lo que usted esperaba inicialmente. Esto le ahorrará muchas conjeturas y rascarse la cabeza cuando tenga que escribir expresiones regulares más complejas.
Qué son exactamente las expresiones regulares – Terminología
Básicamente, una expresión regular es un patrón que describe una cierta cantidad de texto. Su nombre proviene de la teoría matemática en la que se basan. Pero no vamos a profundizar en eso. Normalmente encontrará el nombre abreviado como «regex» o «regexp». Este tutorial utiliza «regex», porque es fácil de pronunciar el plural «regexes». En este sitio web, las expresiones regulares están sombreadas en gris como regex.
Este primer ejemplo es en realidad una regex perfectamente válida. Es el patrón más básico, simplemente coincide con el texto literal regex. Una «coincidencia» es el trozo de texto, o la secuencia de bytes o caracteres que el software de procesamiento de regex encontró que correspondía al patrón.
\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\b.[A-Z]{2,}\b es un patrón más complejo. Describe una serie de letras, dígitos, puntos, guiones bajos, signos de porcentaje y guiones, seguidos de una arroba, seguida de otra serie de letras, dígitos y guiones, y finalmente seguida de un solo punto y dos o más letras. En otras palabras: este patrón describe una dirección de correo electrónico. Esto también muestra el resaltado de sintaxis aplicado a las expresiones regulares.
Con el patrón de expresión regular anterior, puede buscar en un archivo de texto para encontrar direcciones de correo electrónico, o verificar si una cadena dada se parece a una dirección de correo electrónico. Este tutorial utiliza el término «cadena» para indicar el texto al que se aplica la expresión regular. El término «cadena» o «cadena de caracteres» es utilizado por los programadores para indicar una secuencia de caracteres. En la práctica, puedes utilizar expresiones regulares con cualquier dato al que puedas acceder mediante la aplicación o el lenguaje de programación con el que estés trabajando.
Diferentes motores de expresiones regulares
Un «motor» de expresiones regulares es una pieza de software que puede procesar expresiones regulares, tratando de hacer coincidir el patrón con la cadena dada. Normalmente, el motor es parte de una aplicación más grande y no se accede al motor directamente. Más bien, la aplicación lo invoca por ti cuando es necesario, asegurándose de que la expresión regular correcta se aplica al archivo o a los datos correctos.
Como es habitual en el mundo del software, los diferentes motores de expresiones regulares no son totalmente compatibles entre sí. La sintaxis y el comportamiento de un motor en particular se llama sabor de expresión regular. Este tutorial cubre todos los sabores populares de expresiones regulares, incluyendo Perl, PCRE, PHP, .NET, Java, JavaScript, XRegExp, VBScript, Python, Ruby, Delphi, R, Tcl, POSIX, y muchos otros. El tutorial le avisa cuando estos sabores requieren una sintaxis diferente o muestran un comportamiento diferente. Incluso si su aplicación no está explícitamente cubierta por el tutorial, es probable que utilice un tipo de regex que está cubierto, ya que la mayoría de las aplicaciones se desarrollan utilizando uno de los entornos de programación o bibliotecas regex que se acaban de mencionar.
Pruebe las regex por primera vez
Puede probar fácilmente lo siguiente en un editor de texto que soporte expresiones regulares, como EditPad Pro.
Puede probar fácilmente lo siguiente en un editor de texto que soporte expresiones regulares, como EditPad Pro. Si no tiene tal editor, puede descargar la versión de evaluación gratuita de EditPad Pro para probarlo. El motor de regex de EditPad Pro es totalmente funcional en la versión de demostración.
Buscando usando expresiones regulares con EditPad Pro
Como prueba rápida, copie y pegue el texto de esta página en EditPad Pro. Luego seleccione Buscar|Panel de Búsqueda Multilínea en el menú. En el panel de búsqueda que aparece cerca de la parte inferior, escriba regex en la caja etiquetada como «Texto de búsqueda». Marque la casilla «Expresión regular» y haga clic en el botón Buscar primero. Este es el botón más a la izquierda del panel de búsqueda. Vea cómo el motor regex de EditPad Pro encuentra la primera coincidencia. Haga clic en el botón Buscar siguiente, que se encuentra al lado del botón Buscar primero, para encontrar más coincidencias. Cuando no hay más coincidencias, el icono del botón Buscar siguiente parpadea brevemente.
Ahora intente buscar utilizando la expresión regular reg(ular expressions?|ex(p|es)?). Este regex encuentra todos los nombres, singulares y plurales, que he utilizado en esta página para decir «regex». Si sólo tuviéramos una búsqueda en texto plano, habríamos necesitado 5 búsquedas. Con las regex, sólo necesitamos una búsqueda. Las regexes le ahorran tiempo cuando utiliza una herramienta como EditPad Pro. Seleccione Count Matches en el menú Search para ver cuántas veces esta expresión regular puede coincidir con el archivo que tiene abierto en EditPad Pro.
Si usted es un programador, su software se ejecutará más rápido ya que incluso un simple motor regex aplicando la regex anterior una vez superará a un algoritmo de búsqueda de texto plano de última generación buscando a través de los datos cinco veces. Las expresiones regulares también reducen el tiempo de desarrollo. Con un motor de expresiones regulares, sólo se necesita una línea (por ejemplo, en Perl, PHP, Python, Ruby, Java o .NET) o un par de líneas (por ejemplo, en C utilizando PCRE) de código para, por ejemplo, comprobar si la entrada del usuario parece una dirección de correo electrónico válida.
TABLA DE CONTENIDOS de las expresiones regulares:
Introducción
La introducción indica el alcance del tutorial y los tipos de expresiones regulares que se discuten. También introduce la terminología básica.
Caracteres literales y caracteres especiales
El regex más simple consiste sólo en caracteres literales. Ciertos caracteres tienen un significado especial en una regex y deben ser escapados. Las reglas de escape pueden ser un poco complicadas cuando se utilizan regexes en el código fuente del software.
Caracteres no imprimibles
Los caracteres no imprimibles, como los caracteres de control y los caracteres especiales de espaciado o de salto de línea, son más fáciles de introducir utilizando escapes de caracteres de control o escapes hexadecimales.
Cómo funciona internamente un motor Regex
Primero mire el funcionamiento interno del motor de expresiones regulares. Los temas posteriores se basan en esta información. Conocer el funcionamiento interno del motor le ayudará a crear expresiones regulares que coincidan con lo que usted desea, y no con lo que no quiere.
Clases de caracteres o conjuntos de caracteres
Una clase de caracteres o un conjunto de caracteres coincide con un único carácter de entre varios posibles, compuesto por caracteres individuales y/o rangos de caracteres. Una clase de caracteres negada coincide con un solo carácter que no está en la clase de caracteres.
Clases de caracteres taquigráficos
Las clases de caracteres taquigráficos le permiten utilizar rápidamente conjuntos de caracteres comunes. Puede utilizar las clases abreviadas por sí solas o como parte de las clases de caracteres.
Sustracción de clases de caracteres
La sustracción de clases de caracteres le permite hacer coincidir un carácter que está presente en un conjunto de caracteres pero que no está presente en otro conjunto de caracteres.
Intersección de clases de caracteres
La intersección de clases de caracteres le permite hacer coincidir un carácter que está presente en un conjunto de caracteres y que también está presente en otro conjunto de caracteres.
El punto
El punto coincide con cualquier carácter, aunque normalmente no con los caracteres de salto de línea, a menos que cambie una opción.
Acento circunflejo
Las anclas son de longitud cero. No coinciden con ningún carácter, sino con una posición. Hay anclas que coinciden con el inicio y el final de la cadena de asunto, y anclas que coinciden con el inicio y el final de cada línea.
Límites de palabra
Los límites de palabra son como las anclas, pero coinciden con el inicio de una palabra y/o el final de una palabra.
Alternancia
Al separar diferentes sub-reglas con barras verticales, puede indicarle al motor regex que las intente de izquierda a derecha, y que devuelva el éxito tan pronto como una de ellas pueda coincidir.
Elementos opcionales
Si se coloca un signo de interrogación después de un elemento, se le indica al motor regex que lo haga coincidir si es posible, pero que continúe de todos modos (en lugar de admitir la derrota) si no puede coincidir.
Repetición con varios cuantificadores
Tres estilos de operadores, la estrella, el signo más y las llaves, le permiten repetir un elemento cero o más veces, una o más veces, o un número arbitrario de veces. Es importante entender que estos cuantificadores son «codiciosos» por defecto, a menos que los haga explícitamente «perezosos».
Agrupación
Al colocar paréntesis alrededor de una parte de la expresión regular, se indica al motor que trate esa parte como un solo elemento al aplicar los cuantificadores o que agrupe las alternativas. Los paréntesis también crean grupos de captura que permiten reutilizar el texto coincidente con parte de la expresión regular.
Referencias posteriores
Las referencias inversas a los grupos de captura coinciden con el mismo texto que fue coincidido previamente por ese grupo de captura, lo que permite coincidir con patrones de texto repetido.
Grupos con nombre y retro-referencias
Las expresiones regulares que tienen varios grupos son mucho más fáciles de leer y mantener si se utilizan grupos de captura con nombre y referencias posteriores con nombre.
Grupos de reinicio de rama
Cuando se utiliza la alternancia para coincidir con diferentes variantes de la misma cosa, se pueden poner las alternativas en un grupo de restablecimiento de rama. Entonces todas las alternativas comparten los mismos grupos de captura. Esto le permite utilizar las referencias previas o recuperar parte del texto coincidente sin tener que comprobar cuál de las alternativas lo ha capturado.
Espaciado libre y comentarios
Dividir una expresión regular en varias líneas, añadiendo comentarios y espacios en blanco, facilita su lectura y comprensión.
Caracteres y propiedades Unicode
Si su expresión regular soporta Unicode, entonces puede utilizar tokens especiales de regex Unicode para coincidir con caracteres Unicode específicos, o para coincidir con cualquier carácter que tenga una determinada propiedad Unicode o que forme parte de un guión o bloque Unicode particular.
Modificadores de modo
Modifican los modos de coincidencia, como «insensible a mayúsculas y minúsculas», para partes específicas de la expresión regular.
Agrupación atómica y cuantificadores posesivos
Los cuantificadores anidados pueden causar una cantidad exponencialmente creciente de retroceso que hace que el motor regex se detenga. La agrupación atómica y los cuantificadores posesivos ofrecen una solución.
Búsqueda con aserciones de longitud cero, parte 1 y parte 2
Con lookahead y lookbehind, denominados colectivamente lookaround, puede encontrar coincidencias seguidas o no seguidas por cierto texto, y precedidas o no precedidas por cierto texto, sin que el texto precedente o siguiente se incluya en la coincidencia regex general. También puede utilizar la búsqueda para comprobar la misma parte de la coincidencia para múltiples requisitos.
Mantener el texto coincidente hasta el momento fuera de la coincidencia regex general
Mantener el texto coincidente fuera de la coincidencia regex general le permite encontrar coincidencias que están precedidas por cierto texto, sin que ese texto precedente se incluya en la coincidencia regex general. Este método es interesante sobre todo con las variantes de regex que no soportan o soportan poco el lookbehind.
Condicionales
Un condicional es una construcción especial que primero evalúa una búsqueda o retro-referencia, y luego ejecuta una sub-regex si la búsqueda tiene éxito, y otra sub-regex si la búsqueda falla.
Recursión
La recursión hace coincidir toda la expresión regular de nuevo en un punto determinado dentro de la expresión regular, lo que permite hacer coincidir construcciones equilibradas.
Llamadas a subrutinas
Las llamadas a subrutinas permiten escribir expresiones regulares que coinciden con las mismas construcciones en varios lugares sin tener que duplicar partes de la expresión regular.
Recursión, subrutinas y captura
Los grupos de captura dentro de la recursión y las llamadas a subrutinas son manejados de manera diferente por los sabores de regex que los soportan.
Referencias posteriores con nivel de recursión
Las retro-referencias especiales coinciden con el texto almacenado por un grupo de captura en un nivel de recursión particular, en lugar del texto coincidido más recientemente por ese grupo de captura.
Recursión, subrutinas y retroceso
Las variantes de regex que admiten la recursión y las llamadas a subrutinas realizan un seguimiento diferente cuando falla una recursión o una llamada a subrutina.
Expresiones de corchetes POSIX
Si está utilizando un motor de expresión regular compatible con POSIX, puede utilizar expresiones de corchetes POSIX para coincidir con caracteres dependientes de la localización.
Problemas con las coincidencias de longitud cero
Cuando una expresión regular puede encontrar coincidencias de longitud cero, los motores de expresiones regulares utilizan diferentes estrategias para evitar quedarse atascados en una coincidencia de longitud cero cuando se quiere iterar sobre todas las coincidencias de una cadena. Esto puede llevar a resultados de coincidencia diferentes.
Continuación del intento de coincidencia anterior
Forzar una coincidencia regex para que comience al final de una coincidencia anterior proporciona una forma eficiente de analizar los datos de texto.