Documente Academic
Documente Profesional
Documente Cultură
Expresiones Regulares
Monografı́a del Curso Lenguajes Formales y Autómatas
Integrantes
2 de diciembre de 2018
2
Dedicatoria
Primeramente a Dios por habernos permitido llegar hasta este punto y habernos dado
salud, ser el manantial de vida y darnos lo necesario para seguir adelante dı́a a dı́a para
lograr nuestros objetivos, además de su infinita bondad y amor.
A nuestras madres por habernos apoyado en todo momento, por sus consejos, sus
valores, por la motivación constante que nos ha permitido ser personas de bien, pero
más que nada, por su amor. A nuestros padres por los ejemplos de perseverancia y
constancia que lo caracterizan y que me ha infundado siempre, por el valor mostrado
para salir adelante y por su amor y a todos aquellos que ayudaron directa o indirecta-
mente a realizar este documento.
A nuestra maestra por su gran apoyo y motivación ofrecida en este trabajo, por ha-
bernos transmitidos los conocimientos obtenidos y habernos llevado pasó a paso en el
aprendizaje.
3
Agradecimientos
Agradecemos a nuestra profesora Pedro Huamán Sofı́a Raymunda por brindarnos su
guı́a y sabidurı́a en el desarrollo de este trabajo.
4
Resumen
En este trabajo de investigación trataremos sobre un tema de mucha importancia en la
computación y la informática como es sobre las expresiones regulares. Las expresiones
regulares se utilizan como solución al problema de realizar búsquedas de 2 caracteres
en una cadena de 10 o un patrón definido en un archivo de millones de caracteres, las
Expresiones Regulares (ER) constituyen un potente mecanismo para realizar manipu-
laciones y/o búsquedas de cadenas de texto. En el cuerpo de este trabajo monográfico
trataremos sobre muchos aspectos de las expresiones regulares tales como su defini-
ción, descripción, su relación con la programación, su creación, entre otros aspectos
que desarrollaremos en las siguientes páginas, además de eso al terminar con la parte
teórica de esta monografı́a aplicaremos todos los conocimientos que hemos adquirido
para realizar una aplicación utilizando expresiones regulares.
Abstract
In this research work, I will discuss a topic of great importance in computing and
computing as well as regular expressions. Regular expressions become a system of mi-
llions of characters; expressions become a mechanism to perform manipulations and
/ or searches of text strings. In the body of this monographic work we will deal with
many aspects of the expressions expressions such as their definition, description, their
relation with programming, their creation, among other aspects that we will develop
in the following pages, in addition to the end with the theoretical part from this mo-
nograph we will apply all the knowledge we have acquired to make an application with
regular expressions.
This application we will use a programming language is that that in the area of pro-
gramming regular expressions are a method by which you can perform searches within
the strings. No matter how broad the search. In addition, as a result of the search of
the patterns, the validation of a specific format in a given string of characters, such as
dates or identifiers.
6
Introducción
A veces necesitamos encontrar algo concreto en un texto o cadena, o reemplazar un
texto por otro, ya sea en una aplicación, o en un lenguaje de programación. Por ejem-
plo, si queremos buscar ”tag reemplazarlo por .etiqueta”podemos utilizar chartr. La
2
mayorı́a de aplicaciones o lenguajes tienen una función para realizar estas acciones de
forma sencilla. Pero a veces lo que queremos hacer es más complejo, porque puede
que, en vez de ser una palabra o parte de palabra simple, necesitemos hacer algo como
”búscame todas las palabras que acaben en ’f’ y que empiecen por un número del 2
al 71.o reemplaza las palabras que contengan este grupo de letras por esto”. En estos
casos podemos utilizar las expresiones regulares (que suelen llamarse regex.o regexp”de
forma abreviada), que son como un lenguaje para poder definir exactamente qué es lo
que queremos buscar o reemplazar.
Las expresiones regulares vienen a ser una forma sofisticada de hacer un buscar y
reemplazar. En el mundo Windows no tienen mucho sentido, después de todo allı́ casi
todo va a base de clicks. Pero en el mundo Unix/Linux, en el que casi todo son ficheros
de texto, son casi una herramienta imprescindible. No tan solo de cara al administrador,
sino también de cara a cualquier otro programador que puede ver como las expresiones
regulares le salvan la vida en más de una ocasión. La notación de conjuntos nos per-
mite describir los lenguajes regulares, pero nosotros quisiéramos una notación en que
las representaciones de los lenguajes fueran simplemente texto (cadenas de caracteres).
Ası́ las representaciones de los lenguajes regulares serian simplemente palabras de un
lenguaje (el de las representaciones correctamente formadas) es por eso que viene apa-
recer el concepto de expresiones regulares.
Habiendo dado a entender que es una expresión regular que será el tema principal
de esta monografı́a, podemos dar a conocer muchos aspectos que engloban este tema
y ası́ poder aprender con más profundidad las expresiones regulares.
Índice general
1. Expresiones Regulares 9
1.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2. Usos o Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3. Reglas de ER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.4. Leyes Algebraicas Para ER . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.5. Operaciones de los Lenguajes Regulares . . . . . . . . . . . . . . . . . . 11
1.6. Operandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.7. Precedencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.8. Construcción de Expresiones Regulares . . . . . . . . . . . . . . . . . . 12
1.9. Autómatas Finitos y Expresiones Regulares . . . . . . . . . . . . . . . 12
1.10. Aplicaciones de las Expresiones Regulares . . . . . . . . . . . . . . . . 13
1.11. Algebra de las Expresiones Regulares . . . . . . . . . . . . . . . . . . . 13
1.12. Análisis Léxico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4. Algoritmo LZW 25
4.1. Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2. Construcción del Diccionario . . . . . . . . . . . . . . . . . . . . . . . . 26
4.3. Comprensión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.4. Descomprensión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.5. Ejemplo de Comprensión y Descompresión LZW . . . . . . . . . . . . . 27
4.6. Ejemplo del Algoritmo LZW . . . . . . . . . . . . . . . . . . . . . . . . 29
4.7. Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.8. Algoritmo LZW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.9. Diferente Aproximación al Algoritmo LZW . . . . . . . . . . . . . . . . 32
4.9.1. Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
8 ÍNDICE GENERAL
5. Conclusiones 35
Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Capı́tulo 1
Expresiones Regulares
1.1. Definición
Las Expresiones Regulares (ER) constituyen un potente mecanismo para realizar
manipulaciones y/o búsquedas de cadenas de texto. (Muccio, 2008)
Son la notación estándar para caracterizar secuencias de texto. (Franciso, 2015)
Una expresión regular es un patrón de búsqueda que al aplicarse a una lı́nea de texto,
nos dice si contiene o no el patrón. (Franciso, 2015)
Una expresión regular es un patrón que puede estar formado por un conjunto de estar
formado por un conjunto de caracteres (letras, números o signos) y por un conjunto de
metacaracteres que representan otros caracteres o que indican la forma de combinar
los caracteres. (Jamie, 2009)
Los metacaracteres reciben este nombre reciben este nombre porque no se representan
a ellos mismos, sino que son interpretados de una manera especial. (Jamie, 2009)
9
10 CAPÍTULO 1. EXPRESIONES REGULARES
Identificar las palabras que están entre una palabra de negación y un signo de
puntuación. (Franciso, 2015)
1.3. Reglas de ER
Se denominan expresiones regulares sobre un alfabeto A, a las expresiones que se
pueden construir a partir de las siguientes reglas: (UNCPBA, 2009)
es una expresión regular que describe el lenguaje {}, esto es el lenguaje que
contiene únicamente la cadena vacı́a. (UNCPBA, 2009)
Para cada sı́mbolo a ∈ A, a es una expresión regular que describe el lenguaje {a},
esto es el lenguaje que contiene únicamente la cadena a. (UNCPBA, 2009)
Si r y s son expresiones regulares que describen los lenguajes L(r) y L(s) respec-
tivamente:
Las expresiones regulares describen los lenguajes regulares (aquellos reconocidos por
autómatas finitos). (UNCPBA, 2009)
Por ejemplo las siguientes son expresiones regulares válidas: (UNCPBA, 2009)
1. r + φ ≡ φ + r ≡ r
2. r. ≡ .r ≡ r
3. r.φ ≡ φ.r ≡ φ
4. r + s ≡ s + r
5. (r + s) + t ≡ r + (s + t)
6. (r.s).t ≡ r.(s.t)
9. r + r ≡ r
10. φ∗ ≡
11. r.r∗ ≡ r∗ .r
12. r.r∗ + ≡ r∗
14. (r∗ )∗ ≡ r∗
1.6. Operandos
1. Si E y F son expresiones regulares, entonces E + F también lo es denotando la
unión de L(E) y L(F). L(E + F) = L(E) ∪ L(F). (Anónimo, s.f.-b)
1.7. Precedencia
1. El asterisco de la cerradura tiene la mayor precedencia. (Anónimo, s.f.-b)
El álgebra de las expresiones regulares sigue también este patrón, utilizando cons-
tantes y variables que representan lenguajes y operadores para las tres operaciones
mencionadas. (Rafael, 2015)
Ya hemos demostrado que los autómatas finitos deterministas y los dos tipos de autóma-
tas finitos no deterministas (con y sin transiciones ) aceptan la misma clase de len-
guajes. Para demostrar que las expresiones regulares definen la misma clase, tenemos
que probar que: (Marelia, 2015)
1. Todo lenguaje definido mediante uno de estos autómatas también se define me-
diante una expresión regular. Para demostrar esto, podemos suponer que el len-
guaje es aceptado por algún AFD. (Marelia, 2015)
2. Todo lenguaje definido por una expresión regular puede definirse mediante uno
de estos autómatas. Para esta parte de la demostración, lo más sencillo es probar
que existe un AFN con transiciones- que acepta el mismo lenguaje. (Marelia,
2015)
En este capı́tulo, enunciamos una serie de leyes algebraicas que permiten analizar más a
fondo la cuestión de la equivalencia de dos expresiones regulares. En lugar de examinar
expresiones regulares especı́ficas, vamos a considerar parejas de expresiones regulares
con variables como argumentos. Dos expresiones con variables son equivalentes si al
14 CAPÍTULO 1. EXPRESIONES REGULARES
sustituir las variables por cualquier lenguaje, el resultado de las dos expresiones es el
mismo lenguaje. (Rafael, 2015)
Este componente explora el programa fuente y reconoce todas las unidades sintácticas,
aquellas subcadenas de caracteres consecutivos que forman agrupaciones lógicas. Las
palabras clave y los identificadores son ejemplos habituales de este tipo de unidades
sintácticas, aunque existen muchas otras. (Rafael, 2015)
El comando UNIX lex y su versión GNU, flex, acepta como entrada una lista de expre-
siones regulares, escritas en el estilo UNIX, seguidas cada una de ellas por una sección
de código entre corchetes que indica lo que el analizador léxico hará cuando encuentre
una instancia de una unidad sintáctica. (Rafael, 2015)
Tal facilidad se conoce como generador de analizadores léxicos, porque toma como
entrada una descripción de alto nivel de un analizador léxico y genera a partir de ella
una función que es un analizador léxico que funciona. Comandos como lex y flex son
extremadamente útiles porque la notación de las expresiones regulares permite descri-
bir exactamente las unidades sintácticas. (Rafael, 2015)
generación manual del analizador léxico, podı́a llevar meses de trabajo. Además, si
necesitamos modificar el analizador léxico por cualquier razón, basta con cambiar una
o dos expresiones regulares, en lugar de tener que sumergirnos en un misterioso código
para poder solucionar un error. (Rafael, 2015)
Construcción de Expresiones
Regulares
Las tablas siguientes se utilizan para usar algunos ejemplos habituales de las expre-
siones regulares. Para especificar una expresión regular, añada un operador .REG. antes
del patrón. (Recuperado de https://bbvaopen4u.com/es/actualidad/expresiones
-regulares-en-programacion-ejemplos-practicos-para-javascript)
17
18 CAPÍTULO 2. CONSTRUCCIÓN DE EXPRESIONES REGULARES
Ası́ como existen los mencionados sı́mbolos para contar y agrupar y clases de
caracteres existen delimitadores de patrones, estos pueden indicar el inicio de la cadena
o el final de la cadena, y también existen las secuencias de escape y cadenas literales.
(Recuperado de https://bbvaopen4u.com/es/actualidad/expresiones-regulares
-en-programacion-ejemplos-practicos-para-javascript)
Todos los demás caracteres como, por ejemplo, [-], [/], entre otros, solo pueden
ser constantes.
(Recuperado de http://docs.trendmicro.com/all/smb/hes/vAll/es-es/olh/
ag/policy rules criteria keyword about.html)
Los rangos de variables sólo pueden ser de A-Z y 0-9; no se pueden limitar los
rangos a, por ejemplo, A-D.
(Recuperado de http://docs.trendmicro.com/all/smb/hes/vAll/es-es/olh/
ag/policy rules criteria keyword about.html)
Las expresiones regulares generadas por esta herramienta distinguen entre mayúscu-
las y minúsculas.
(Recuperado de http://docs.trendmicro.com/all/smb/hes/vAll/es-es/olh/
ag/policy rules criteria keyword about.html)
Las expresiones regulares generadas por esta herramienta solo pueden realizar
coincidencias positivas, no negativas (”si no coincide”).
2.3. SINTAXIS EN EXPRESIONES COMPLEJAS 19
(Recuperado de http://docs.trendmicro.com/all/smb/hes/vAll/es-es/olh/
ag/policy rules criteria keyword about.html)
Los operadores son: .AND., .OR., .NOT., .NEAR., .OCCUR., .WILD., .(.and.). El
operando y el operador deben estar separados por un espacio. Un operando también
puede contener varios testigos. (Recuperado de http://docs.trendmicro.com/all/
smb/hes/vAll/es-es/olh/ag/policy rules criteria keyword about.html)
Figura 3: Pantallazo.
Para implementar esta aplicación utilizamos en java dos objetos Matcher y Pat-
tern de la librerı́a java.util.regex , estos son básicamente dos objetos que nos
permiten buscar coincidencias en cadenas de texto utilizando ciertos patrones.
Lo primero que se hace es permitir ingresar una cadenas de texto a través del
objeto scanner y declaramos dicha cadena a evaluar, luego creamos un ciclo while
pero antes declaramos el regex, que vendrı́a a ser la expresión regular, siguiendo
con el ciclo while dentro del bucle asignamos a regex para que este sea exacta-
mente igual a la próxima lı́nea de cadena de texto en el scanner, esto lo utilizamos
para escanear una expresión regular desde el teclado y lo guardamos en la variable
regex.
Luego ya finalizando con el código creamos una variable booleana llamada coinci-
dencia, utilizando el m.find esto lo que hace es buscar e este objeto con el patrón
y la cadena de texto para ver si el regex tiene una coincidencia
2.5. IMPLEMENTACIÓN EN JAVA SOBRE EXPRESIONES REGULARES 21
Figura 4: Salida.
Cadena: Es una secuencia finita de sı́mbolos tomados del alfabeto. (Jair, 2007)
Patrón: Es una regla que describe el conjunto de lexemas que pueden representar
a un determinado componente léxico(Token) en los programas. (Jair, 2007)
23
24CAPÍTULO 3. LAS EXPRESIONES REGULARES Y SU RELACIÓN CON LOS AF
Capı́tulo 4
Algoritmo LZW
Desarrollado por J. Ziv y A. Lempel (1977), y refinado por T. Welch (1984). Usado
en los ficheros de formato gráfico GIF y TIFF. Estos algoritmos (compresión y des-
compresión) son sorprendentemente simples. (Edwin, 2012)
LZW utiliza una tabla de cadenas y reemplaza cadenas de caracteres por códigos úni-
cos. Es suficiente con añadir el último carácter que ha entrado a una cadena existente
en la tabla para añadir esta nueva cadena a dicha tabla entonces se crea un nuevo
ı́ndice para esa cadena. (Edwin, 2012)
“En los datos comprimidos no está cargada la tabla de cadenas. Sólo se carga la tabla
de caracteres individuales y los códigos que se han obtenido como salida.” (Edwin,
2012)
4.1. Historia
Abraham Lempel y Jakob Ziv son los creadores del compresor LZ77, inventado en
1977 (de ahı́ su nombre). Este compresor se utilizó en ese momento para archivar (los
formatos ZIP, ARJ y LHA lo utilizan). (Anónimo, s.f.-a)
LZW es un algoritmo muy rápido tanto para la compresión como para la descompre-
sión, basado en la multiplicidad de aparición de secuencias de caracteres en la cadena
que se debe codificar. Su principio consiste en sustituir patrones con un código de ı́ndice
y construir progresivamente un diccionario. (Anónimo, s.f.-a)
25
26 CAPÍTULO 4. ALGORITMO LZW
4.3. Comprensión
El algoritmo pasa por la cadena de información y la codifica. Si una cadena nunca
es más corta que la palabra más larga del diccionario, ésta se transmite. (Anónimo,
s.f.-a)
Cada vez que un nuevo código es obtenido, una nueva cadena es añadida a la tabla de
cadenas de caracteres. Inicialmente, en la tabla se encuentra los caracteres individuales
que se pueden encontrar en el fichero. Lo normal es que los ı́ndices de la tabla de 0-255
sean asignados a los caracteres ASCII, y los restantes, sean asignados a las cadenas
que se van añadiendo a la tabla. El algoritmo de compresión seria: (Edwin, 2012)
4.4. Descomprensión
Durante la descompresión, el algoritmo reconstruye el diccionario en la dirección
opuesta; por lo tanto, no necesita almacenarse. (Anónimo, s.f.-a)
=3
4.7. Programación
El primer programa tiene dos partes diferenciadas una primera la de compresión y
otra segunda la de descompresión, que con la filosofı́a del algoritmo LZW, funcionan de
manera similar creando las dos el diccionario de forma iterativa mientras se codifican
o descodifican los datos entrantes. (Borja, 2014)
El unordered-map es una función de C++11 que permite crear una matriz de rápido
acceso y que puede relacionar de forma interna datos de diferente tipo. Esta función
utiliza un hash para ubicar el dato en una posición de memoria. El tamaño del diccio-
nario más óptimo es de 2 a la 16, con este tamaño se evita el problema de tener que
restablecer el diccionario de 0 cada vez que este se llena por completo. (Borja, 2014)
30 CAPÍTULO 4. ALGORITMO LZW
Aquı́ ya se inicializan las 255 primeras entradas del diccionario tal como dicta el al-
goritmo anteriormente expuesto. A partir de este momento empieza el bucle compresor
que funcionara hasta encontrar el EOF (end of file) del archivo. (Borja, 2014)
Con esta simple función se comprueba si el dato se encuentra dentro del diccionario
o no, gracias a la función FIND de la clase unordered-map. (Borja, 2014)
Si el dato se encuentra se procederá a leer el siguiente dato y con str igual str
mas ch; concatenarlo con el anterior y volver a comprobar si se encuentra dentro del
diccionario. Si el dato no se encuentra dentro del diccionario es añadido al diccionario
como un nuevo dato en la siguiente posición vacı́a del mismo. (Borja, 2014)
Justo después se procederá a buscar el str, sin el último dato leı́do, en el diccionario.
(Borja, 2014)
Por este motivo se planteó esta otra aproximación al algoritmo con la complejidad
normalizada que hace que el cálculo sea menos dependiente del tamaño del archivo y
por lo tanto más óptimo para el tipo de datos que se pretenden tratar. (Borja, 2014)
4.9.1. Programación
En esta implementación se utiliza un sistema de administración de datos distinta
al de la primera aproximación, debido a que necesitaremos recorrer todos los datos
en busca de nuevas subsecuencias. Esta búsqueda se hace de forma recursiva, ası́ que
leeremos todos los datos y los guardaremos en un vector de pairs que nos permite
asociar dos tipos de datos distintos y trabajar conjuntamente con ellos. (Borja, 2014)
El vector se ira creando de forma dinámica con cada dato 0 o0 y ı́ndice 0 i0 . (Borja,
2014)
Una vez almacenados los datos junto con su ı́ndice, dentro del vector los datos
son ordenados de mayor a menor con un sort para acotar de esta forma el número de
sı́mbolos disponibles en 100; numero al que se ha llegado con varias pruebas buscando
el compromiso entre velocidad del algoritmo y precisión del cálculo. (Borja, 2014)
Una vez sustituidos los sı́mbolos deshacemos el sort con el ı́ndice anteriormente
creado en el vector de pairs volviendo a tener el vector en el orden inicial pero con los
nuevos sı́mbolos. (Borja, 2014) Para ello se hace uso de un vector auxiliar de tamaño
de memoria ya reservado y que nos permite dejar de lado el vector de pairs que cuyo
uso es más pesado y costoso para un procesador. (Borja, 2014)
Este bucle se encara de administrar las variables tal como indica el algoritmo
aumentando el contador en 1 cada vez que se encuentra una nueva secuencia. (Borja,
2014)
Conclusiones
Las expresiones regulares actúan como un buscador avanzado para filtrar solo in-
formación necesaria o útil y que es relevante para un fin determinado.
Una expresión regular solo se podrá utilizar cuando exista un patrón dentro del código.
La clave del algoritmo LZW reside en que es posible crear sobre la marcha, de ma-
nera automática y en una única pasada un diccionario de cadenas que se encuentren
dentro del texto a comprimir mientras al mismo tiempo se procede a su codificación.
Una de las caracterı́sticas más primordiales del algoritmo LZW es que los códigos
en la salida se representan por cadenas de bits variables.
35
36 CAPÍTULO 5. CONCLUSIONES
Referencias
Anónimo. (s.f.-a). Comprensión lzw. https://es.ccm.net/contents/731-compresion-lzw-
.
Anónimo. (s.f.-b). Expresiones regulares. https://ccc.inaoep.mx/ emorales/Curso-
s/Automatas/ExpRegulares.pdf.
Borja, G. (2014). Estudio de implementacion del algoritmo lzw en una plataforma zynq
7000 de xilinx. Universidad Politecnica de Valencia, España.
Edwin, D. (2012). Comprension y descomprension, universidad nacional jorge basadre
grohmann, tacna, perú.
Franciso, B. (2015). Uso ingenioso de las expresiones regulares.
Jair, V. (2007). Conocer, utilizar y manipular expresiones regulares, departamento de
ciencias aplicadas. Universidad Autonoma del Estado de México, México.
Jamie, Z. (2009). Javascript: Expresiones regulares, departamento de lenguajes y sis-
temas informáticos. Universidad de Alicante, España.
Marelia, B. (2015). Aplicación de las expresiones regulares a los automatas finitos
problemas.
Muccio, A. y. C. O. (2008). Expresiones regulares, facultad de ingenierı́a. Buenos
Aires.
Rafael, M. (2015). Expresiones regulares.
UNCPBA. (2009). Regulares y expresiones regulares, facultad de ciencias exactas.