Expresiones Regulares
Son patrones de texto mediantes los cuales se pueden optimizar actividades de busqueda y reconocimiento de segmentos de cadenas de caracteres en un archivo especifico o en un conjunto de ellos. Algunos ejemplos de lo que puede hacerse con re son cosas como:
- Comprobar o validar que una entrada en un formulario HTML sea una dirección de correo electrónico válida.
- Inspeccionar si un patrón de texto aparece en un archivo. esto puede ser l busqued de una palabra o un porción de la misma en un documento.
- Extraer porciones de texto de un documento. Ej: extraer el código postal de una dirección.
- Reemplazar partes de un texto. Ej: Cambiar «Azúl» por «Rojo» en un documento.
Como podemos apreciar la aplicabilidad es extensa pero la agilidad obtenida en l manipulación de grandes porciones de archivos es una compensación hasta adictiva para todos aquellos que pretendan automatizar tareas rutinarias, que de otra mnera serian tediosamente largas y en la práctica una sincera perdida de tiempo. Las re son independientes del lenguaje que se este usando.
Antecedentes:
- Warren McCulloch and Walter Pitts NeuroFísicos publicaron «A logical calculus of the ideas immanent in nervous activity.» (1943). Este paper no solo representa el inicio de las re sino que también propone el primer modelo matemático para redes neuronales.
- Stephen Kleene, escribió el paper «Representation of events in nerve nets and finite automata» (1956), donde acuñó los terminos regular sets y regular expressions.
- Doce años después un ingeniero publica: «Regular Expression Search Algorithm» Ken Thompson (1968), Ken es conocido por ser diseñador e implementador en UNIX del lenguaje B, el UTF-8, entre otros trabajos.
- El próximo hito importante fue la introducción de una biblioteca no propietaria de regex por Henry Spence y más tarde la creación del lenguaje de guiones PERL por Larry Wall. PERL agregó muchas modificaciones a la sintaxis de regex creando lo que se conoce como «Perl Flavor» o los sabores de perl. Muchas de las implementaciones posteriores en el resto de los lenguajes se basan en el perl flavor.
- la IEEE a través del estandar POSIX intentó un mejor soporte Unicode para regex esto se conoce como el «POSIX flavor».
- Ahora mismo python posee un módulo para regex que soporta el estilo perl Documentación python regex module. Además del ya archi conocido modulo estandar para python2 y python3.
Definiciones:
Una Regex es un patrón de texto que consiste en caracteres ordinarios precedidos por «/» y metcarateres precedidos por «\».
Metacaracteres:
Caracteres con un significado especial para las búsquedas. Tienen un significado especial cuando se utilizan en una expresión de búsqueda.
Comienzo y final de una línea: El «^» (acento circunflejo) hace referencia al comienzo de la línea en una búsqueda y el «$» (signo dólar) tiene referencia con el final de la línea.
/^www/
/$com/
Comodines: Regex tiene muchos aspectos heredados de [ed](https://es.wikipedia.org/wiki/Ed_(Unix) recordar cada uno de ellos se torna dificil, porque el significado de un simbolo depende de dónde se utilice en una expresión. Por ejemplo, en modo de entrada un punto «.» (punto) es simplemente un carácter ordinario de texto, salvo que se encuentre sólo en una línea, en cuyo caso significa «vuelve al modo orden». En modo orden, el «.» significa «cualquier carácter». Así, la orden:
/a..b/
significa «encuentra una a y una b separadas por tres caracteres cualesquiera». La orden:
/./
significa «encuentra cualquier carácter» (excepto un carácter de nueva-línea). Cuando el «.» punto aparece en el lado derecho de una expresión de sustitución, significa «un punto». Esto puede combinarse en una única orden:
.s/././
Esta orden muestra todos los significados de un «.» en una expresión. El primer «.» significa «en la línea actual sustituya (para cualquier carácter) un punto (.)» por Ejemplo:
p
Buenos días
s/././
.uenos días
El * (asterisco). «Tantas ocurrencias como ocurran incluyendo ninguna». Así la orden:
> s/xx*/y/
da instrucciones que en ed sustituyen dos o más ocurrencias de «x» por una única «y». La orden:
> s/x.*y/Y
significa «sustituye el carácter Y por cualquier cadena que comience por una «x» y finalice con una «y» separadas por cualquier número de caracteres». Las cadenas «xqwertyy», «xasdy» y «xy» serían sustituidas por «Y».
Recomendación: Todos estos ejemplos se pueden ejecutar desde el shell con la instrucción [«sed»](https://es.wikipedia.org/wiki/Sed_(inform%C3%A1tica) texto simple por ejemplo:
> sed -i 's/x.*y/Y/' ejemplo.txt
El & (ampersand). el & es una abreviación que ahorra mucha escritura. Supongamos que se quiere cambiar:
> Este proyecto ha sido un éxito.
por
> (Este proyecto ha sido un éxito.)
Podría utilizar la orden
s/Este proyecto ha sido un éxito./(Este proyecto ha sido un éxito.)/
Pero utilizando «&» se simplifica a:
> s/Este proyecto ha sido un éxito./(&)/
Clases de caracteres en la búsqueda:[]
Se pueden especificar clases de cosas a buscar, para lo cual se usa «[]» por ejemplo:
> [xy]
representa a la clase de letras minúsculas que son «x» o «z» de está forma:
> /[xz]/
buscará la siguiente «x» o la siguiente «z» de la expresión.
> [fF]
«f» en minúsculas o mayúsculas, en consecuencia la orden de búsqueda:
> /[fF]reddy/
encontrará a «freddy» y «Freddy». La expresión:
> [0123456789]
buscará cualquier dígito, pero se puede simplicar con:
> [0-9]
que representá toodos los caracteres en el rango «0» al «9». La orden quedará:
> /[0-9]/
ahora:
> [A-Z]
representa todos los caracteres del rango de la «A» a la «Z». para definir un caracter que no se encuentr en está clase utilizar el «^» circunflejo entre los corchetes «[^]» lo cual representa cualquier carácter no incluido en los corchetes. la expresión siguiente:
> [^0-9]
representa cualquier carácter que no este entre «0» y «9»; en otras palabras, cualquier carácter que no sea un dígito.
caracteres especiales en Regex Tabla 1
Carácter | Significado |
---|---|
«.» | Cualquier carácter distinto de nueva línea. |
«*» | Cero o más ocurreencias del caracter anterior. |
«.*» | Cero o más ocurrencias de cualquier carácter. |
«^» | Comienzo de línea. |
«$» | Final de línea. |
«[–]» | Identifica a la clase de caracteres definida entre corchetes. |
«[^–]» | Identifica a cualquier carácter no incluido en la clase definida entre corchetes. |
«\» | Caraćter de escape; trata al siguiente carácter, «X» como una X literal |
Desactivación de caracteres especiales:
Los caracteres $ [] * son parte de la sintaxis de las Regex, todos tienen un significado especial en las búsquedas. Vea la Tabla 1. Ahora bien ¿qué pasa si queremos buscar uno de esos caracteres en un archivo? ¿qué ocurre si se necesita encontrar el «$» en una memoria? El carácter «\» Backslash se utiliza par desactivar ese significado especial de los metacaracteres. Un metacarácter precedido de un \ significá el carácter literal. Si usted teclea:
> / . /
el interprete buscaría cualquier carácter, la siguiente orden, sin embargo:
> / \ . /
busca un punto «.» literalmente y no cualquier carácter. La siguiente orden:
> / \ * /
busca un * literalmente. Y por supuesto:
> / \ \ /
busca un «\» Backslash literal. y
> / \ $ /
busca un «$»
Estos patrones de busqueda pueden ser usados de distintas formas uno de los usos que particularmente le doy es con grep (dato curioso el nombre de este comando viene de la forma que tiene el editor ed para las busquedas g/re/p o global/regular expression/print), que es una utilidad de UNIX para desde la shell ubicar una línea en un archivo específico que coincida con un patrón un ejemplo sería:
> grep -InRi '^[mM]*ay' mbox.txt
> 54165:May have missed an end tag
en el anterior obtengo una lista númerada de las líneas dentro del archivo mbox.txt que coinciden con la expresión regular entre comillas simples. Espero que ya te estes percatando del poder de las Regex. Otra buena idea es usar guiones (scripts) para sed o ed, con lo cual podemos realizar tareas super rápidas de modificación sobre archivos si quieres profundizar sobre el tema recomiendo el siguiente enlace.