Expresiones regulares y autómatas finitos
Expresiones regulares y autómatas finitos
Expresiones regulares y autómatas finitos
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Oliver A. Vilca H. Pág. 1<br />
<strong>Expresiones</strong> <strong>regulares</strong> y autómatas <strong>finitos</strong><br />
Resumen de clases<br />
Oliver Amadeo Vilca Huayta<br />
Una expresión regular sirve como un descriptor de un lenguaje, también es una herramienta para<br />
describir patrones de texto, por ejemplo:<br />
1. Se utiliza una notación similar a una expresión regular para describir patrones de búsqueda.<br />
Por ejemplo en el procesamiento de documentos electrónicos, bioinformática, base de datos y en<br />
comandos de búsqueda como el GREP de UNIX.<br />
2. En los generadores de analizadores léxico como el Lex y el Flex. El análisis léxico es una fase de<br />
un compilador que divide el código de entrada en unidades lógicas denominadas tokens de uno<br />
o más caracteres. Ejemplos de tokens son las palabras reservadas (ejemplo: if ), identificadores<br />
y signos como +,>.<br />
3. En búsqueda de texto flexible, se utiliza la expresión regular como un patrón de búsqueda, por<br />
ejemplo: a??bc[f-p] puede represetar a todas las cadenas (palabras) de texto que inician con la a<br />
seguida de cualquier dos carateres (símbolos), seguida de bc, y, finalmente un carater que puede<br />
ser desde la f hasta la k, es decir, uno del rango de carateres comprendido entre la f y k.<br />
Una ventaja adicional es que se puede convertir en una máquina (autómata finito), el cual puede<br />
automáticamente decidir si una cadena (palabra) pertenece o no al lenguaje denotado por la expresión<br />
regular.<br />
Cadena Una cadena (o algunas veces palabra) es una secuencia finita de símbolos escogidos de un<br />
alfabeto. Por ejemplo: aba es una cadena del alfabeto Σ = {a, b}<br />
La cadena vacia. Es la cadena de cero ocurrencias de símbolos, es denotado por ǫ.<br />
Longitud de una cadena. Es el número de símbolos (posiciones) de una cadena. Por ejemplo aba tiene<br />
longitud 3. La notación para la longitud de una cadena w es |w|. Y |ǫ| = 0 (la única cadena cuya<br />
longitud es cero).<br />
La estrella de Kleene (o la clausura de Kleene). De un lenguaje L se denota por L ∗ . Es la unión<br />
infinita ∪ i≥0 L i , donde L 0 = {ǫ}, L 1 = L y L i , para i > 1 es LLL · · · L, la concatenación de i copias de L.<br />
Expresión regular. Se puede describir una expresión regular recursivamente como sigue:<br />
Las constantes ǫ (cadena vacia) y ∅ (conjunto vacio) son expresiones <strong>regulares</strong>.<br />
Si a ∈ Σ, es un símbolo, entonces a es una expresión regular.<br />
Inducción: Si r y s son expresiones <strong>regulares</strong> entonces:<br />
r|s es una expresión regular, denota la unión de los lenguajes que representan dichas expresiones<br />
<strong>regulares</strong>.<br />
rs es una expresión regular, denota la concatenación.<br />
r ∗ es una expresión regular, denota la estrella de kleene.<br />
(r) es una expresión regular, denota el mismo lenguaje r.<br />
Nota: Debido a que en algunos casos el operador “|” (unión) no está muy accesible en el teclado del<br />
computador, en algunas aplicaciones como el JFLAP se utiliza el + y algunos autores lo utilizan<br />
Precedencia: Para evitar el uso exagerado de paréntesis se puede emplear la precedencia de operadores.<br />
Borrador<br />
1. Operador unario “∗”: Tiene la mayor precedencia y es asociativo por la izquierda, es decir, se<br />
aplica sólo a la secuencia más corta de símbolos a su izquierda que constituye una expresión<br />
regular.<br />
2. La concatenación, o “punto”: tiene la segunda mayor precedencia y es asociativo por la izquierda.<br />
Este operador se representa con un punto, pero por fines prácticos se obvia, en su lugar se<br />
ubican los símbolos
Oliver A. Vilca H. Pág. 2<br />
3. La unión “|”: tiene la menor precedencia y es asociativo por la izquierda.<br />
En ocasiones no se desea que una expresión regular sea agrupada según la precedencia de los operadores.<br />
En dicho caso, se puede emplear paréntesis para agrupar los operandos de la forma que se<br />
requiera. por conveniencia.<br />
Ejemplos:<br />
Complete los espacios en blanco.<br />
Lenguaje regular Expresión regular<br />
{a, b}<br />
{ǫ, b}<br />
{a, ab}<br />
{abe, ace, _____}<br />
{a, b, c, d}<br />
{ǫ, b, bb, bbb, bbbb, ...}<br />
{a, ab, abb, abbb, abbbb, ...}<br />
{ǫ, c, ab, cc, ccc, cccc, ...}<br />
{a, ab, abb, abbb, abbbb, . . .<br />
ac, abc, abbc, abbbc, abbbbc, . . .}<br />
Todas las cadenas que se pueden<br />
formar con el alfabeto Σ = {a, b}, incluido<br />
la cadena vacia<br />
a|b<br />
ǫ|b<br />
a|ab = a(ǫ|b)<br />
a(b|c|d)e<br />
(a|b)(a|b)<br />
(a|b)|(c|d) = a|b|c|d<br />
b ∗<br />
ab ∗ c<br />
ab|c ∗<br />
ab ∗ (ǫ|c) = ab ∗ |ab ∗ c<br />
a ∗ |b ∗<br />
a ∗ b ∗<br />
(a|b) ∗<br />
(ab) ∗<br />
Lenguajes cuyas clausuras no son infinitas: ∅ ∗ = {ǫ}. Asimismo, ∅ 0 = {ǫ}, mientras que ∅ i , para algun<br />
i ≥ 1 es vacio, debido a que no se puede seleccionar alguna cadena del conjunto vacio. Finalmente ǫ ∗<br />
= {ǫ}.<br />
Ejemplo: Construya una expresión regular para:<br />
L = {w ∈ {a,b}* : w tiene una cantidad par de a’s }<br />
Si se tratara solamente de a’s la respuesta sería: (aa) ∗ el cual genera una cantidad par de a’s (cero<br />
es par). Pero es necesario considerar el alfabeto Σ = {a, b} ∗ el cual permite la cadena como: babba,<br />
baabababb.<br />
La respueta es: (b ∗ ab ∗ ab ∗ ) ∗ que también puede escribirse: (b|ab ∗ a) ∗<br />
Ejemplo: Dado el lenguaje formado sobre el alfabeto Σ = {a, b} donde se tiene la condición de que<br />
cada b esta precedida por una a (pueden haber mas a’s que la preceden). Por ejemplo: ǫ, aaabaa, ababa,<br />
aaa.<br />
L = {w ∈ {a, b} ∗ : en w cada b está precedido por al menos una a}<br />
Respuesta: (a|ab) ∗<br />
Borrador<br />
Ejemplo: Dado el lenguaje formado con el alfabeto Σ = {a, b} donde todas las cadenas no tienen la<br />
subcadena aa ni la subcadena bb. Es decir, el siguiente lenguaje:<br />
L = {w ∈ {a, b} ∗ : w no tiene la subcadenas “aa ′ ni “bb ′′ }<br />
Solución: Para obtener el resutado se ordena las cadenas (que se pueden generar) en tres filas como<br />
sigue:
Oliver A. Vilca H. Pág. 3<br />
ǫ<br />
a, ab, aba, abab, ababa, ababab, . . .<br />
b, ba, bab, baba, babab, bababa, . . .<br />
Para generar el primer conjunto de cadenas (primera y segunda fila) se tiene: (ab) ∗ (a|ǫ). A este resultado<br />
se le debe incluir el segundo conjunto de cadenas, siendo el resultado: (ab) ∗ (a|ǫ)|(ba) ∗ (b|ǫ). Si se<br />
observa mas el ejercicio se obtiene: (b|ǫ)(ab) ∗ (a|ǫ)<br />
Algebra de expresiones <strong>regulares</strong><br />
Complete los espacios en blanco.<br />
Lenguaje regular<br />
La clausura de ∅: ∅ ∗<br />
ǫ ∗<br />
Ley de idempotencia para la unión: r|r<br />
Elemento neutro de la unión: ∅|r = ∅|r<br />
Elemento neutro de la concatenación: ǫr = ǫr<br />
Elemento nulo de la concatenación: ∅r = ∅r<br />
Clausura de una expresión que ya está clausurada: (r ∗ ) ∗<br />
<strong>Expresiones</strong> <strong>regulares</strong> en Unix/Linux<br />
Resultado<br />
Por conveniencia en el Unix/Linux se utiliza una notación extendida de expresiones <strong>regulares</strong> para<br />
facilitar su uso, considerando las características y restricciones de la computadora (ejemplo códigos).<br />
Se presenta una breve descripción sin desviarse en detalles.<br />
Permite escribir clases de caracteres para representar grandes conjuntos cadenas lo mas compacto<br />
posible. Sus reglas son las siguientes:<br />
El símbolo . “representa cualquier caracter”.<br />
La secuencia [c 1 c 2 · · · c n ] representa la expresión regular: c 1 |c 2 | · · · |c n<br />
Por ejemplo se puede utilizar para representar los cuatro caracteres utilizados en los operadores<br />
de comparación del C/C++ [=!].<br />
La secuencia [c 1 c 2 · · · c n ] representa cualquier caracter que no sea: c 1 |c 2 | · · · |c n<br />
Rango [x − y] que significa todos los caracteres de x hasta y en la secuencia ASCCI. Por ejemplo<br />
las letras mayúsculas se pueden representar como [A − Z] y el conjunto de todas las letras y<br />
dígitos como [A − Za − z0 − 9]. Los corchetes y otros caracteres reservados del UNIX pueden<br />
representarse precediéndolos con \.<br />
Ejemplos del comando GREP del Unix:<br />
$ # Buscar líneas con al menos una letra de la a a la z (minúsculas o mayúsculas).<br />
$ grep ’[a-zA-Z]’ sistemas.txt<br />
$ # Lista líneas con cualquier carácter que no sean ni letra ni número.<br />
$ grep ’[a-zA-Z0-9]’ archivo.txt<br />
<strong>Expresiones</strong> <strong>regulares</strong> para el programador<br />
Borrador<br />
A continuación algunas de las herramientas de programación disponibles que ofrecen motores de<br />
búsqueda con soporte para expresiones <strong>regulares</strong>:
Oliver A. Vilca H. Pág. 4<br />
Java: existen varias bibliotecas hechas para java que permiten el uso de RegEx, y Sun planea<br />
dar soporte a estas desde el SDK.<br />
JavaScript: a partir de la versión 1.2 (ie4+, ns4+) JavaScript tiene soporte integrado para expresiones<br />
<strong>regulares</strong>.<br />
PCRE: biblioteca de ExReg para C, C++ y otros lenguajes que puedan utilizar bibliotecas dll<br />
(Visual Basic 6 por ejemplo).<br />
.Net Framework: provee un conjunto de clases mediante las cuales es posible utilizar expresiones<br />
<strong>regulares</strong> para hacer búsquedas, reemplazar cadenas y validar patrones.<br />
Ejercicios propuestos<br />
1. Verdadero o Falso. Explique su respuesta:<br />
(a) a* ⊂ a*b*<br />
(b) a*b* ∩ b*a* = a* | b*<br />
(c) abab ∈ (a(cd)*b)*<br />
(d) abcd ∈ (a*(cd)*b*)*<br />
2. Verdadero o Falso. Explique su respuesta:<br />
(a) b*a* | a*b* = (a|b)*<br />
(b) abcd ∈ (a(cd)*b)*<br />
(c) (a|b) ∗ = (a ∗ b ∗ ) ∗<br />
(d) (ab|a)*ab = (aa*b)*<br />
3. Escriba una expresión regular para los siguientes lenguajes:<br />
(a) {w ∈ {0,1}* : w tiene una cantidad de 1’s divisible por cinco }<br />
(b) {w ∈ {a,b}* : w no tiene tres b’s consecutivas } Es decir, cadenas que tienen a lo mas dos b’s<br />
consecutivas.<br />
(c) {w ∈ {a,b}* : w tiene exactamente una ocurrencia de bbb }<br />
(d) {w ∈ {a,b}* : w no tiene la subcadena aba }<br />
4. Escriba una expresión regular para el siguiente lenguaje: [6p]<br />
L = {a m b n : m + n es par }<br />
5. Desmuestre o refute lo siguiente: (ab|a) ∗ = (aa ∗ b) ∗ [5p]<br />
6. Demuestre ó refute que: a ∗ b(ba ∗ b|a) ∗ = a ∗ b(a ∗ ba ∗ ba ∗ ) ∗ [5p]<br />
7. Escriba una expresión regular para la diferencia de los siguientes lenguajes: a ∗ b ∗ − b ∗ [5p]<br />
8. Derivadas de expresiones <strong>regulares</strong>, fue introducido por Brzozowski 1 . Sea E una expresión<br />
regular sobre un alfabeto Σ y sean a y b dos símbolos distintos de Σ. La derivada de E con<br />
respecto a a (de longitud unitaria), se define recursivamente como sigue: [8p]<br />
∂<br />
(a)<br />
∂a<br />
= ǫ (1)<br />
∂<br />
∂a (ǫ) = ∂ ∂a (∅) = ∂ (b)<br />
∂a<br />
= ∅ (2)<br />
∂<br />
∂a (F ∗ ) = ∂ ∂a (F )F ∗ (3)<br />
<br />
∂<br />
∂<br />
∂a (F G) = ∂a<br />
(G) Si ǫ ∈ F,<br />
∂<br />
∂a (F )G En otro caso. (4)<br />
1 Janusz A. Brzozowski (1964) Derivatives of regular expressions.<br />
Borrador
Oliver A. Vilca H. Pág. 5<br />
Derive: (a|b) ∗ a(a|b) 2 respecto a a y b.<br />
Defina la derivada de una expresión regular E respecto a una cadena w de Σ ∗ .<br />
Borrador