Sunteți pe pagina 1din 36

UNIVERSIDAD NACIONAL DE TRUJILLO

Expresiones Regulares
Monografı́a del Curso Lenguajes Formales y Autómatas

Integrantes

Alcántara Bejarano, Leydi


Cárdenas Galloso, Adrian
Velásquez Benites, Yordy
Zurita Ruiz, Robert

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.

Dicha aplicación lo haremos utilizando un lenguaje de programación es por eso que


en el área de la programación las expresiones regulares son un método por el cual se
pueden realizar búsquedas dentro de cadenas de caracteres. Sin importar lo amplio de
la búsqueda requerida de un patrón definido de caracteres, las expresiones regulares
proporcionan una solución práctica al problema. Adicionalmente, un uso derivado de
la búsqueda de patrones es la validación de un formato especı́fico en una cadena de
caracteres dada, como por ejemplo fechas o identificadores.
5

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.

El objetivo de las expresiones regulares es representar todos los posibles lenguajes


definidos sobre un alfabeto Σ, en base a una serie de lenguajes primitivos, y unos ope-
radores de composición; los lenguajes primitivos: el lenguaje vacı́o, el lenguaje formado
por la palabra vacı́a, y los lenguajes correspondientes a los distintos sı́mbolos del alfa-
beto; operadores de composición: la unión, la concatenación y el cierre.

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

2. Construcción de Expresiones Regulares 17


2.1. Ejemplos de Expresiones Regulares . . . . . . . . . . . . . . . . . . . . 17
2.2. Generador de Expresiones Regulares . . . . . . . . . . . . . . . . . . . 18
2.3. Sintaxis en Expresiones Complejas . . . . . . . . . . . . . . . . . . . . 19
2.4. Búsqueda de Patrones en Textos . . . . . . . . . . . . . . . . . . . . . . 19
2.5. Implementación en Java Sobre Expresiones Regulares . . . . . . . . . . 19

3. Las Expresiones Regulares y su Relación con los AF 23


3.1. Expresiones Regulares . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.2. De los AFD a las Expresiones Regulares . . . . . . . . . . . . . . . . . 23

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

Comenzamos este capı́tulo presentando la notación conocida como “expresiones


regulares”. Estas expresiones es otro tipo de notación para la definición de lenguajes.
También puede pensarse en las expresiones regulares como en un “lenguaje de progra-
mación”, en el que es posible escribir algunas aplicaciones importantes, como por ejem-
plo aplicaciones de búsqueda de texto o componentes de compilador. Las expresiones
regulares están estrechamente relacionadas con los autómatas finitos no deterministas
y pueden considerarse una alternativa, que el usuario puede comprender fácilmente,
a la notación de los AFN para describir componentes de software. En este capı́tulo,
después de definir las expresiones regulares, demostraremos que éstas pueden definir
todos los lenguajes regulares y sólo estos.

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)

1.2. Usos o Funciones


Buscar todos los precios en un texto. (Franciso, 2015)
Identificando todos los strings que sean como $1.999 o $1’000.000. (Franciso,
2015)
Buscar todas las palabras que empiecen por mayúscula en un texto.
Identificar los URLs en un tweet o status de Facebook. (Franciso, 2015)

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)

Comandos de búsqueda, ejemplo, grep de UNIX.

Sistemas de formateo de texto: Usan notación de tipo expresión regular para


describir patrones.

Convierte la expresión regular a un DFA o un NFA y simula el autómata en el


archivo de búsqueda.

Generadores de analizadores-léxicos. Como Lex o Flex.

Los analizadores léxicos son parte de un compilador. Dividen el programa fuente


en unidades lógicas (tokens), como while, números, signos (+, −, <, etc.)

Produce una DFA que reconoce el token.

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 vacı́o. (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:

1. r + s es una expresión regular que describe el lenguaje L(r) ∪L (s)(UNCPBA,


2009)
2. r . s es una expresión regular que describe el lenguaje L(r) . L(s) (UNCPBA,
2009)
3. r* es una expresión regulatenacir que describe el lenguaje L(r)*. El operador
de clausura es el que tiene mayor precedencia, seguido por el operador de
concaón y por último el operador de unión. (UNCPBA, 2009)

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)

a* . b que describe el lenguaje L = {an b/n ≥ 0} (UNCPBA, 2009)

(a + b)* que describe el lenguaje L = {x/x ∈ {a, b}∗ } (UNCPBA, 2009)


1.4. LEYES ALGEBRAICAS PARA ER 11

1.4. Leyes Algebraicas Para ER


Dos expresiones regulares r y s son equivalentes (r ≡ s) si L(r) = L(s). Sean r, s y t
expresiones regulares: (Recuperado de: http://www.exa.unicen.edu.ar/catedras/
ccomp1/ApunteGryER.pdf)

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)

7. r.(s + t) ≡ r.s + r.t

8. (s + t).r ≡ s.r + t.r

9. r + r ≡ r

10. φ∗ ≡ 

11. r.r∗ ≡ r∗ .r

12. r.r∗ +  ≡ r∗

13. (r∗ .s∗ )∗ ≡ (r + s)∗

14. (r∗ )∗ ≡ r∗

1.5. Operaciones de los Lenguajes Regulares


1. Unión: Si L y M son dos lenguajes, su unión se denota por L ∪ M (ejemplo,
L = {11, 00}, M = {0, 1}, L ∪ M = {0, 1, 00, 11}) (Anónimo, s.f.-b)

2. Concatenación: La concatenación es: LM o L.M (ejemplo, LM = {110, 111, 000, 001})


(Anónimo, s.f.-b)

3. Cerradura (o cerradura de Kleene): Si L es un lenguaje su cerradura se denota


por: L∗ (L0 = {}, L1 = L, L2 = LL. SiL = {0, 11}, L2 = {00, 011, 110, 1111})
(Anónimo, s.f.-b)
12 CAPÍTULO 1. EXPRESIONES REGULARES

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)

2. Si E y F son expresiones regulares, entonces EF también lo es denotando la


concatenación de L(E) y L(F). L(EF) = L(E)L(F). (Anónimo, s.f.-b)

3. Si E es una expresión regular, entonces E* también lo es y denota la cerradura


de L(E). Ósea L(E*) = (L(E))* (Anónimo, s.f.-b)

4. Si E es una expresión regular, entonces (E) también lo es. Formalmente: L((E))


= L(E). (Anónimo, s.f.-b)

1.7. Precedencia
1. El asterisco de la cerradura tiene la mayor precedencia. (Anónimo, s.f.-b)

2. Concatenación sigue en precedencia a la cerradura, el operador ”dot”. Concate-


nación es asociativa y se sugiere agrupar desde la izquierda (012 se agrupa (01)2).
(Anónimo, s.f.-b)

3. La unión (operador +) tiene la siguiente precedencia, también es asociativa.


(Anónimo, s.f.-b)

4. Los paréntesis pueden ser utilizados para alterar el agrupamiento. (Anónimo,


s.f.-b)

1.8. Construcción de Expresiones Regulares


Todos los tipos de álgebras se inician con las expresiones elementales, que normal-
mente son constantes y/o variables. Las álgebras nos permiten construir más expre-
siones aplicando un cierto conjunto de operadores a las expresiones elementales y a
las expresiones previamente construidas. Normalmente, también se necesitan algunos
métodos que permitan agrupar operadores con sus operandos, tales como los parénte-
sis. Por ejemplo, la familiar álgebra de la aritmética se inicia con constantes, como los
números enteros y reales, más las variables y se construyen expresiones más complejas
utilizando operadores aritméticos como + y ×. (Rafael, 2015)

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)

1.9. Autómatas Finitos y Expresiones Regulares


Aunque las expresiones regulares describen los lenguajes de manera completamente
diferente a como lo hacen los autómatas finitos, ambas notaciones representan exacta-
mente el mismo conjunto de lenguajes, que hemos denominado “lenguajes regulares”.
1.10. APLICACIONES DE LAS EXPRESIONES REGULARES 13

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)

Figura 1: Esquema de demostración de equivalencia de cuatro notaciones diferentes


para los lenguajes regulares.

1.10. Aplicaciones de las Expresiones Regulares


Una expresión regular que proporciona una “imagen” del patrón que deseamos re-
conocer es el medio que emplean las aplicaciones que permiten realizar búsquedas de
patrones en textos. (Rafael, 2015)

Las expresiones regulares a continuación se compilan entre bastidores para obtener


autómatas deterministas o no deterministas, que luego se simulan para generar un pro-
grama que reconoce los patrones en los textos. En esta sección, vamos a considerar dos
clases importantes de aplicaciones basadas en expresiones regulares: los analizadores
léxicos y la búsqueda de textos. (Rafael, 2015)

1.11. Algebra de las Expresiones Regulares


Hemos visto la necesidad de simplificar las expresiones regulares, con el fin de man-
tener un tamaño manejable de las mismas. (Rafael, 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)

A continuación, proporcionamos un ejemplo de este proceso aplicado al álgebra de


la aritmética. Es evidente que 1 + 2 = 2 + 1. Esto es un ejemplo de la ley conmutativa
de la suma, y es fácil comprobarlo aplicando el operador de la suma en ambos lados de
la igualdad para obtener 3 = 3. Sin embargo, la ley conmutativa de la suma dice más;
establece que x + y = y + x, donde x e y son variables que pueden reemplazarse por dos
números cualesquiera. Es decir, independientemente de los dos números que se sumen,
se obtiene el mismo resultado sea cual sea el orden en que se sumen. Al igual que las
expresiones aritméticas, las expresiones regulares cumplen una serie de leyes. Muchas
de éstas son similares a las leyes aritméticas, si interpretamos la unión como una suma
y la concatenación como una multiplicación. Sin embargo, hay algunas ocasiones en
las que la analogı́a no se aplica. También existen algunas leyes que se aplican a las ex-
presiones regulares, pero no tienen su análoga en la aritmética, especialmente cuando
se utiliza el operador de clausura. Las siguientes secciones se ocupan de las principales
leyes. Terminaremos con una exposición acerca de cómo puede comprobarse si una ley
propuesta para las expresiones regulares es efectivamente una ley; es decir, se cumple
para cualquier lenguaje por el que sustituyamos las variables. (Rafael, 2015)

1.12. Análisis Léxico


Una de las aplicaciones más antiguas de las expresiones regulares es la de especi-
ficar el componente de un compilador conocido como “analizador léxico”. (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)

Estos comandos pueden emplearse en el proceso de conversión de expresiones regu-


lares en un AFD, para generar una función eficiente que separe los programas fuentes
en unidades sintácticas. (Rafael, 2015)

Realizan la implementación de un analizador léxico en muy poco tiempo, mientras


que antes del desarrollo de estas herramientas basadas en expresiones regulares, la
1.12. ANÁLISIS LÉXICO 15

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)

Figura 2: Análisis léxico.


16 CAPÍTULO 1. EXPRESIONES REGULARES
Capı́tulo 2

Construcción de Expresiones
Regulares

Las expresiones regulares se utilizan para realizar la coincidencia de cadenas. Con-


sulte las tablas siguientes para conocer algunos ejemplos habituales de las expresiones
regulares. Para especificar una expresión regular, añada un operador .REG. antes del
patrón.

2.1. Ejemplos 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)

Tabla 1: Algunos sı́mbolos para contar y agrupar.

17
18 CAPÍTULO 2. CONSTRUCCIÓN DE EXPRESIONES REGULARES

Tabla 2: Algunas clases de caracteres.

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)

2.2. Generador de Expresiones Regulares


Al decidir cómo configurar las reglas para la prevención de pérdida de datos, ten-
ga en cuenta que el generador de expresiones regulares sólo puede crear expresiones
sencillas en función de las siguientes reglas y limitaciones: (Recuperado de http://docs
.trendmicro.com/all/smb/hes/vAll/es-es/olh/ag/policy rules criteria keyword
about.html)

Las variables sólo pueden ser caracteres alfanuméricos.


(Recuperado de http://docs.trendmicro.com/all/smb/hes/vAll/es-es/olh/
ag/policy rules criteria keyword about.html)

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)

Las expresiones basadas en el ejemplo solo pueden obtener coincidencias con el


número exacto de caracteres y espacios del ejemplo; la herramienta no puede
generar patrones que coincidan con üna o variası̈nstancias de un determinado
carácter o cadena.
(Recuperado de http://docs.trendmicro.com/all/smb/hes/vAll/es-es/olh/
ag/policy rules criteria keyword about.html)

2.3. Sintaxis en Expresiones Complejas


Una expresión de palabra clave está formada por testigos, que es la unidad más
pequeña usada para hacer coincidir la expresión con el contenido. Un testigo puede ser
un operador, un sı́mbolo lógico o el operando, es decir, el argumento o el valor sobre el
que actúa el operador. (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)

2.4. Búsqueda de Patrones en Textos


El problema general para el que la tecnologı́a basada en expresiones regulares ha
resultado ser útil es la descripción de clases de patrones de texto definidos vagamente.
La vaguedad de la descripción prácticamente garantiza que no definiremos correcta-
mente el patrón a la primera, quizá puede que nunca lleguemos a obtener exactamente
la descripción correcta. Utilizando la notación de las expresiones regulares, será fácil
describir el patrón en un nivel alto, con poco esfuerzo, y modificar la descripción rápi-
damente cuando las cosas no funcionen. Un “compilador” para expresiones regulares
es útil para convertir las expresiones que hemos escrito en código ejecutable.

2.5. Implementación en Java Sobre Expresiones Re-


gulares
Como ya sabemos una expresión regular es una forma para describir en un set de
cadenas de texto caracterı́sticas en común y eso sirve para buscar coincidencias en-
tre un patrón dado y una cadena de texto ya existente. (Recuperado de http://docs
.trendmicro.com/all/smb/hes/vAll/es-es/olh/ag/policy rules criteria keyword
about.html)
20 CAPÍTULO 2. CONSTRUCCIÓN DE EXPRESIONES REGULARES

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.

Ahora colocamos una secuencia de salida con un if y hacemos un break para


que termine el programa sino es asi se sigue con el programa; lo primero que se
hace para evaluar la cadena ingresada vamos a crear el patrón a través del objeto
pattern y para eso hacemos un pattern.compile que es básicamente un método
que esta integrado en el objeto y lo que hace es agarrar una cadena de texto que
es el regex .

Despues creamos un objeto llamado matcher, este es el busca la coincidencia entre


la cadena de texto ingresada y el patrón, para este caso utlizamos la cadenas de
texto a evaluar

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.

Figura 5: Pruebas de expresiones regular para ver coincidencia.


22 CAPÍTULO 2. CONSTRUCCIÓN DE EXPRESIONES REGULARES
Capı́tulo 3

Las Expresiones Regulares y su


Relación con los AF

3.1. Expresiones Regulares


Alfabeto: Denota cualquier conjunto finito de sı́mbolos. (Jair, 2007)

Sı́mbolo: Representación distinguible de cualquier información. (Jair, 2007)

Cadena: Es una secuencia finita de sı́mbolos tomados del alfabeto. (Jair, 2007)

Lenguaje: Es un conjunto de cadenas de un alfabeto fijo. (Jair, 2007)

Expresiones Regulares: Representan patrones de cadenas de caracteres. (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)

3.2. De los AFD a las Expresiones Regulares


La construcción de una expresión regular para definir el lenguaje de cualquier AFD
tiene truco. Consiste básicamente en construir expresiones que describan conjuntos de
cadenas que etiqueten ciertos caminos del diagrama de transiciones de un AFD. Sin
embargo, estos caminos sólo pueden pasar por un subconjunto limitado de estados. En
una definición inductiva de estas expresiones, partiremos de las expresiones más simples
que describen caminos que no pueden pasar a través de cualquier estado (es decir,
son nodos simples o arcos simples), y construiremos inductivamente las expresiones
que permitan caminos que pasen a través de caminos que progresivamente recorran
conjuntos de estados más grandes. Finalmente, los caminos podrán pasar por cualquier
estado; es decir, las expresiones que generemos al final representarán todos los caminos
posibles. (Marelia, 2015)

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)

En 1978 crearon el compresor LZ78 especializado en compresión de imágenes (o la


compresión de cualquier tipo de archivo binario). (Anónimo, s.f.-a)

En 1984, Terry Welch de Unisys lo modificó para utilizarlo en controladores de disco


duro; por lo tanto, se agregó la inicial de su apellido a la abreviatura LZ, lo que originó
el término LZW. (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)

Además, funciona en bits y no en bytes, por lo tanto, no depende de la manera en

25
26 CAPÍTULO 4. ALGORITMO LZW

que el procesador codifica información. Es uno de los algoritmos más populares y se


utiliza particularmente en formatos TIFF y GIF. Dado que el método de compresión
LZW ha sido patentado por Unisys, el que se utiliza en imágenes PNG es el algoritmo
LZ77, por el que no se pagan derechos de autor. (Anónimo, s.f.-a)

4.2. Construcción del Diccionario


El diccionario comienza con los 256 valores de la tabla ASCII. El archivo a com-
primir se divide en cadenas de bytes (por lo tanto, para las imágenes monocromáticas
codificadas en 1 bit, esta compresión no es muy eficaz), cada una de estas cadenas se
compara con el diccionario y se agrega si no se encuentra ahı́. (Anónimo, s.f.-a)

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)

Figura 6: Diagrama de flujo de la compresión.


4.4. DESCOMPRENSIÓN 27

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)

Necesita poder coger la lista de códigos de salida del algoritmo de compresión y la


tabla inicial de los ı́ndices de caracteres individuales. A partir de estos datos, el algo-
ritmo de descompresión es capaz de reconstruir completamente la tabla de cadenas,
necesaria para poder obtener la entrada. El algoritmo de descompresión es el siguiente:
(Edwin, 2012)

Figura 7: Diagrama de flujo de la descompresión.

4.5. Ejemplo de Comprensión y Descompresión LZW


La cadena de entrada estará formada solamente por 0 A0 , 0 B0 y 0 C0 : ABBABABAC
La tabla inicial está formada por los ı́ndices de estos caracteres: 0 A0 = 1, 0 B0 = 2, 0 C0
28 CAPÍTULO 4. ALGORITMO LZW

=3

Figura 8: Comprensión de datos.

Códigos obtenidos en la compresión (1, 2, 2, 4, 7, 3)

Figura 9: Descompresión de datos.


4.6. EJEMPLO DEL ALGORITMO LZW 29

4.6. Ejemplo del Algoritmo LZW

Figura 10: Ejemplo del algoritmo LZW.

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)

Para la parte de compresión se utilizará un mapa para crear el diccionario. (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)

Para a continuación sacar el dato con la codificación que le otorga el diccionario,


ya que el fputc solo nos permite sacar datos de 8 bits y a partir del 256 los datos
codificados superan los 8 bits primera se extraerán los 8 bits más altos y luego los 8
más bajos con estas operaciones. (Borja, 2014)
4.8. ALGORITMO LZW 31

Para el objetivo del trabajo la extracción de datos en un archivo comprimido no


es del todo necesaria, pero ha sido llevado a cabo para la posterior comprobación con
el descompresor y para ver realmente que la compresión se efectuaba sin ningún tipo
de problema. Finalmente, el último dato leı́do anteriormente pasa a ser el primer dato
con el que continuar las iteraciones del algoritmo. (Borja, 2014)

Una vez la codificación ha sido realizada la complejidad es calculada como el ratio


de compresión conseguido con el algoritmo. La parte de descompresión carece de interés
en este trabajo ya que solo se ha realizado para comprobar que la compresión se está
haciendo de forma correcta. (Borja, 2014)

4.8. Algoritmo LZW


Dada una ”frase”de un alfabeto de M letras, el pseudocódigo del algoritmo es:
(Recuperado de http://alojamientos.us.es/gtocoma/pid/pid6/pid66.htm)
1. Inicializar una tabla (diccionario), asignando a cada letra un código de 0 a M-1.

2. Inicializar C = primera letra de la frase.

3. Sea K el siguiente carácter en la frase.

4. Si CK es una palabra del diccionario


C = CK
ir al paso 3.
En otro caso,
añadir CK al diccionario asignandole un código n no utilizado, c(CK) = n.
C=K
ir al paso 3.
Por ejemplo, supongamos que disponemos de un alfabeto con 3 letras A, B, C. Quere-
mos codificar la palabra ABACABA.

Primero codificamos el alfabeto: c(A) = 0, c(B) = 1, c(C) = 2.

Los pasos del algoritmo son:

La frase codificada serı́a ABACABA=010230 (fijándonos en la primera columna


C).
32 CAPÍTULO 4. ALGORITMO LZW

4.9. Diferente Aproximación al Algoritmo LZW


Tras obtenerse buenos resultados por parte del compresor y realizar varias pruebas
con diferentes datos y diferentes tamaños de datos, fue vista una clara dependencia
entre la efectividad del algoritmo y el tamaño del archivo a ser tratado. Esto es debido
a que la compresión empieza a ser optima una vez el diccionario tiene suficientes datos
para empezar a codificar los datos entrantes, provocando que para conjuntos de datos
de tamaño reducido la ratio de compresión sea altamente dependiente de los datos y
el orden de estos. (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)

A partir de este punto empieza el bucle encargado de buscar subsecuencias dentro


de secuencia total inicial, se inicializan las variables. (Borja, 2014)
4.9. DIFERENTE APROXIMACIÓN AL ALGORITMO LZW 33

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)

Para la búsqueda exhaustiva se llama a la función issubstring(aux,np,nq) que se


encarga de buscar las nuevas secuencias pasándole un vector y el rango valores que ha
de buscar siendo np y nq. (Gastaldo Borja,2014) Este bucle for anidado se encargará
de comparar cada sı́mbolo de PQ con Q para ver si se encuentra dentro devolviendo
un 1 si es parte o un 0 si es un nuevo sı́mbolo. (Borja, 2014)
34 CAPÍTULO 4. ALGORITMO LZW

Esta parte del programa es la más costosa computacionalmente hablando; conforme


va aumentando el tamaño del archivo lo hace el número de veces que se han de recorrer
las posiciones del vector, lastrando el cálculo y haciendo que sea poco viable. (Borja,
2014)
Capı́tulo 5

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.

S-ar putea să vă placă și