Una Introducción a las Expresiones Regulares

Introducción

Como administradores de sistemas, desarrolladores, ingenieros de QA, ingenieros de soporte, etc., a menudo necesitamos encontrar un patrón particular, como un conjunto de direcciones IP pertenecientes a cierto rango, un rango de marcas de tiempo, grupos de nombres de dominio o subdominio, en archivos. También podríamos necesitar encontrar una palabra escrita de una manera específica o buscar posibles errores tipográficos en un archivo. Aquí es donde entran en juego las expresiones regulares.

Las expresiones regulares son plantillas para hacer coincidir patrones (o a veces no hacer coincidir patrones). Proporcionan una forma de describir y analizar texto. Este tutorial proporcionará una visión general de las expresiones regulares sin entrar en las particularidades de ningún lenguaje. Simplemente usaremos egrep para explicar los conceptos.

Expresiones Regulares

Las expresiones regulares consisten en dos tipos de caracteres:

  • los caracteres literales regulares y

  • los metacaracteres

son los que otorgan poder a las expresiones regulares.

Considera el siguiente archivo country.txt donde la primera columna es el nombre del país, la segunda columna es la población del país y la tercera columna es el continente.

$ cat country.txt
India,1014003817,Asia
Italy,57634327,Europe
Yemen,1184300,Asia
Argentina,36955182,Latin America
Brazil,172860370,Latin America
Cameroon,15421937,Africa
Japan,126549976,Asia

Metacaracteres de Anclaje

El primer grupo de “metacaracteres” que discutiremos son ^ y $. ^ y $ coinciden con el inicio y el final de un patrón respectivamente y se llaman metacaracteres de anclaje.

Para encontrar el nombre de todos los países cuyo nombre de país comienza con I, usamos la expresión:

$ egrep '^I' country.txt
India,1014003817,Asia
Italy,57634327,Europe

o para encontrar todos los países que tienen nombres de continentes que terminan con e, hacemos:

$ egrep 'e$' country.txt
Italy,57634327,Europe

El siguiente metacaracter es el punto (.), que coincide con cualquier ún caracter. Para coincidir con todas las líneas en las que el nombre del país tiene exactamente 5 caracteres de longitud:

$ egrep '^.....,' country.txt
India,1014003817,Asia
Italy,57634327,Europe
Yemen,1184300,Asia
Japan,126549976,Asia

¿Qué tal encontrar todas las líneas en las que el nombre del país comienza con I o J y el nombre del país tiene 5 caracteres de longitud?

$ egrep '^[IJ]....,' country.txt
India,1014003817,Asia
Italy,57634327,Europe
Japan,126549976,Asia

[…] se llama un conjunto de caracteres o una clase de caracteres. Dentro de un conjunto de caracteres, solo se coincide con uno de los caracteres dados.

Un ^ dentro del conjunto de caracteres niega el conjunto de caracteres. El siguiente ejemplo coincidirá con nombres de países de cinco caracteres de longitud pero que no comienzan ni con I ni con J.

$ egrep '^[^IJ]....,' country.txt
Yemen,1184300,Asia

El Metacarácter de Agrupación y la Alternancia

Para encontrar todas las líneas que contienen Asia o África:

$ egrep 'Asia|Africa' country.txt
India,1014003817,Asia
Yemen,1184300,Asia
Cameroon,15421937,Africa
Japan,126549976,Asia

Esto también se puede hacer tomando A y a como comunes.

$ egrep 'A(si|fric)a' country.txt
India,1014003817,Asia
Yemen,1184300,Asia
Cameroon,15421937,Africa
Japan,126549976,Asia

Cuantificadores

En lugar de escribir

$ egrep '^[IJ]....,' country.txt

podemos escribir

$ egrep '^[IJ].{4},' country.txt

donde {} se llaman cuantificadores. Determinan cuántas veces debe ocurrir el carácter antes que ellos.

También podemos dar un rango:

$ egrep '^[IJ].{4,6},' country.txt
India,1014003817,Asia
Italy,57634327,Europe
Japan,126549976,Asia

Esto coincidirá con nombres de países que comiencen con I o J y tengan de 4 a 6 caracteres después de ello.

Existen algunos atajos disponibles para los cuantificadores. Por ejemplo,

{0,1} es equivalente a ?

$ egrep '^ab{0,1}c$' filename

es lo mismo que

$ egrep '^ab?c' filename

{0,} es equivalente a *

$ egrep '^ab{0,}c$' filename

es lo mismo que

$ egrep '^ab*c' filename

{1,} es equivalente a +

$ egrep '^ab{1,}c$' filename

es lo mismo que

$ egrep '^ab+c' filename

Veamos algunos ejemplos que involucran las expresiones que hemos visto hasta ahora. Aquí, en lugar de buscar en un archivo, buscamos desde la entrada estándar. El truco que usamos es que sabemos que grep (o egrep) busca un patrón, y si se encuentra un patrón, se muestra toda la línea que contiene el patrón.

Nos gustaría encontrar todas las formas posibles de escribir la oración el traje de color gris era su favorito.

La expresión sería:

$ egrep 'the gr[ea]y colou?r suit was his favou?rite'
the grey color suit was his favourite
the grey color suit was his favourite

the gray colour suit was his favorite
the gray colour suit was his favorite

Observando la expresión anterior, podemos ver que:

  • grey se puede escribir como grey o gray

  • color se puede escribir como colour o color, lo que significa que la u es opcional, por lo que usamos u?

  • similarmente, favorito o favorite se puede escribir favou?rite

¿Qué pasa con hacer coincidir un código postal estadounidense?

$ egrep '^[0-9]{5}(-[0-9]{4})?$'
83456
83456

83456-

834562

92456-1234
92456-1234

10344-2342-345

Un ejemplo más de hacer coincidir todas las horas válidas en un reloj de 24 horas.

$ egrep '^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]'
23:44:02
23:44:02

33:45:11

15:45:33
15:45:33

En el ejemplo anterior dijimos que, si el primer dígito de la hora es 0 o 1, entonces el segundo será cualquiera del 0 al 9. Pero si el primer dígito es 2, entonces los valores permitidos para el segundo dígito son 0, 1, 2 o 3.

Límite de palabra

Para escribir un patrón que coincida con las palabras que terminan con color de modo que se emparejen unicolor, acuarela, multicolor, etc., pero no sin color o colorido. Prueba estos ejemplos tú mismo para familiarizarte con ellos:

$ egrep 'color\>'

A continuación, para hacer coincidir sin color o colorido, pero no unicolor, acuarela, multicolor, etc.

$ egrep '\<color'

Para hacer coincidir exactamente la palabra color, hacemos:

$ egrep '\<color\>'

Retrocesos

Supongamos que queremos hacer coincidir todas las palabras que se escribieron dos veces, como the the o before before, tenemos que usar retrocesos. Los retrocesos se utilizan para recordar patrones.

Aquí hay un ejemplo:

$ egrep "\<the\> \1"

O de manera genérica:

$ egrep "\<(.*)\> \1"

El ejemplo anterior se puede utilizar para encontrar todos los nombres en los que los nombres y apellidos son iguales. En caso de que haya más de un conjunto de paréntesis, entonces el segundo, tercero, cuarto, etc. se pueden referenciar con \2, \3, \4, etc.

Esto es solo una introducción al poder de las expresiones regulares.

Source:
https://www.digitalocean.com/community/tutorials/an-introduction-to-regular-expressions