Академический Документы
Профессиональный Документы
Культура Документы
Una expresin regular, a menudo llamada tambin patrn, es una expresin que describe
un conjunto de cadenas sin enumerar sus elementos. Por ejemplo, el grupo formado por las
cadenas Handel, Hndel y Haendel se describe mediante el patrn "H(a||ae)ndel". La
mayora de las formalizaciones proporcionan los siguientes constructores: una expresin
regular es una forma de representar a los lenguajes regulares (finitos o infinitos) y se
construye utilizando caracteres del alfabeto sobre el cual se define el lenguaje.
Especficamente, las expresiones regulares se construyen utilizando los operadores unin,
concatenacin y clausura de Kleene. Adems cada expresin regular tiene un autmata
finito asociado.
Alternacin
Una barra vertical separa las alternativas. Por ejemplo, "marrn|castao" casa con
marrn o castao.
Cuantificacin
Un cuantificador tras un carcter especifica la frecuencia con la que ste puede
ocurrir. Los cuantificadores ms comunes son +, ? y *:
+
El signo ms indica que el carcter al que sigue debe aparecer al menos una vez. Por
ejemplo, "ho+la" describe el conjunto infinito hola, hoola, hooola, hoooola,
etctera.
?
El signo de interrogacin indica que el carcter al que sigue puede aparecer como
mucho una vez. Por ejemplo, "ob?scuro" casa con oscuro y obscuro.
*
El asterisco indica que el carcter que lo precede puede aparecer cero, una, o ms
veces. Por ejemplo, "0*42" casa con 42, 042, 0042, 00042, etctera.
Agrupacin
Los parntesis pueden usarse para definir el mbito y precedencia de los dems
operadores. Por ejemplo, "(p|m)adre" es lo mismo que "padre|madre", y
"(des)?amor" casa con amor y con desamor.
Los constructores pueden combinarse libremente dentro de la misma expresin, por lo que
"H(ae?|)ndel" equivale a "H(a|ae|)ndel".
La sintaxis precisa de las expresiones regulares cambia segn las herramientas y
aplicaciones consideradas, y se describe con ms detalle a continuacin.
Su utilidad ms obvia es la de describir un conjunto de cadenas, lo que resulta de utilidad
en editores de texto y aplicaciones para buscar y manipular textos. Muchos lenguajes de
programacin admiten el uso de expresiones regulares con este fin. Por ejemplo, Perl tiene
un potente motor de expresiones regulares directamente incluido en su sintaxis. Las
herramientas proporcionadas por las distribuciones de Unix (incluyendo el editor sed y el
filtro grep) fueron las primeras en popularizar el concepto de expresin regular.
Aplicaciones
Numerosos editores de texto y otras utilidades utilizan expresiones regulares para buscar y
reemplazar patrones en un texto.
Java: existen varias bibliotecas hechas para java que permiten el uso de RegEx, y
Sun planea dar soporte a estas desde el SDK
JavaScript: a partir de la versin 1.2 (ie4+, ns4+) JavaScript tiene soporte integrado
para expresiones regulares.
Perl: es el lenguaje que hizo crecer a las expresiones regulares en el mbito de la
programacin hasta llegar a lo que son hoy en da.
PCRE: biblioteca de ExReg para C, C++ y otros lenguajes que puedan utilizar
bibliotecas dll (Visual Basic 6 por ejemplo).
PHP: tiene dos tipos diferentes de expresiones regulares disponibles para el
programador, aunque la variante POSIX (ereg) va a ser desechada en PHP 6.
Python: lenguaje de "scripting" popular con soporte a Expresiones Regulares.
.Net Framework: provee un conjunto de clases mediante las cuales es posible
utilizar expresiones regulares para hacer bsquedas, reemplazar cadenas y validar
patrones.
Nota: de las herramientas mencionadas con anterioridad se utilizan el EditPad Pro y el .Net
Framework para dar ejemplos, aunque es posible utilizar las expresiones regulares con
cualquier combinacin de las herramientas mencionadas. Aunque en general las
Expresiones Regulares utilizan un lenguaje comn en todas las herramientas, las
explicaciones prcticas acerca de la utilizacin de las herramientas y los ejemplos de
cdigo deben ser interpretados de forma diferente. Tambin es necesario hacer notar que
existen algunos detalles de sintaxis de las expresiones regulares que son propietarios del
.Net Framework que se utilizan en forma diferente en las dems herramientas de
programacin. Cuando estos casos se den se har notar en forma explcita para que el lector
pueda buscar informacin respecto a estos detalles en fuentes adicionales. En el futuro se
incluirn adicionalmente ejemplos de otras herramientas y lenguajes de programacin.
Expresiones regulares como motor de bsqueda
Las expresiones regulares permiten encontrar porciones especficas de texto dentro de una
cadena ms grande de caracteres. As, si es necesario encontrar el texto "lote" en la
expresin "el ocelote salt al lote contiguo" cualquier motor de bsqueda sera capaz de
efectuar esta labor. Sin embargo, la mayora de los motores de bsqueda encontraran
tambin el fragmento "lote" de la palabra "ocelote", lo cual podra no ser el resultado
esperado. Algunos motores de bsqueda permiten adicionalmente especificar que se desea
encontrar solamente palabras completas, solucionando este problema. Las expresiones
regulares permiten especificar todas estas opciones adicionales y muchas otras sin
necesidad de configurar opciones adicionales, sino utilizando el mismo texto de bsqueda
como un lenguaje que permite enviarle al motor de bsqueda exactamente lo que deseamos
encontrar en todos los casos, sin necesidad de activar opciones adicionales al realizar la
bsqueda.
Expresiones regulares como lenguaje
Para especificar opciones dentro del texto a buscar se utiliza un lenguaje o convencin
mediante el cual se le transmite al motor de bsqueda el resultado que se desea obtener.
Este lenguaje le da un significado especial a una serie de caracteres. Por lo tanto cuando el
motor de bsqueda de expresiones regulares encuentre estos caracteres no los buscar en el
texto en forma literal, sino que buscar lo que los caracteres significan. A estos caracteres
se les llama algunas veces "meta-caracteres". A continuacin se listan los principales metacaracteres y su funcin y como los interpreta el motor de expresiones regulares.
El Punto "."
El punto es interpretado por el motor de bsqueda como cualquier carcter excepto los
caracteres que representan un salto de lnea, a menos que se le especifique esto al motor de
Expresiones Regulares. Por lo tanto si esta opcin se deshabilita en el motor de bsqueda
que se utilice, el punto le dir al motor que encuentre cualquier carcter incluyendo los
saltos de lnea. En la herramienta EditPad Pro esto se hace por medio de la opcin "punto
corresponde a nueva lnea" en las opciones de bsqueda. En .Net Framework se utiliza la
opcin RegexOptions. Singleline al efectuar la bsqueda o crear la expresin regular.
El punto se utiliza de la siguiente forma: Si se le dice al motor de RegEx que busque "g.t"
en la cadena "el gato de piedra en la gtica puerta de getisboro goot" el motor de bsqueda
encontrar "gat", "gt" y por ltimo "get". Ntese que el motor de bsqueda no encuentra
"goot"; esto es porque el punto representa un solo carcter y nicamente uno. Si es
necesario que el motor encuentra tambin la expresin "goot", ser necesario utilizar
repeticiones, las cuales se explican ms adelante.
Aunque el punto es muy til para encontrar caracteres que no conocemos, es necesario
recordar que corresponde a cualquier carcter y que muchas veces esto no es lo que se
requiere. Es muy diferente buscar cualquier carcter que buscar cualquier carcter
alfanumrico o cualquier dgito o cualquier no-dgito o cualquier no-alfanumrico. Se debe
tomar esto en cuenta antes de utilizar el punto y obtener resultados no deseados.
\t Representa un tabulador.
\r Representa el "retorno de carro" o "regreso al inicio" o sea el lugar en que la
lnea vuelve a iniciar.
\n Representa la "nueva lnea" el carcter por medio del cual una lnea da inicio.
Es necesario recordar que en Windows es necesaria una combinacin de \r\n para
comenzar una nueva lnea, mientras que en Unix solamente se usa \n y en Mac_OS
clsico se usa solamente \r.
\a Representa una "campana" o "beep" que se produce al imprimir este carcter.
Notas:
La barra "|"
Sirve para indicar una de varias opciones. Por ejemplo, la expresin regular "a|e"
encontrar cualquier "a" o "e" dentro del texto. La expresin regular "este|oeste|norte|sur"
permitir encontrar cualquiera de los nombres de los puntos cardinales. La barra se utiliza
comnmente en conjunto con otros caracteres especiales.
El asterisco "*"
El asterisco sirve para encontrar algo que se encuentra repetido 0 o ms veces. Por ejemplo,
utilizando la expresin "[a-zA-Z]\d*" ser posible encontrar tanto "H" como "H1", "H01",
"H100" y "H1000", es decir, una letra seguida de un nmero indefinido de dgitos. Es
necesario tener cuidado con el comportamiento del asterisco, ya que ste, por defecto, trata
de encontrar la mayor cantidad posible de caracteres que correspondan con el patrn que se
busca. De esta forma si se utiliza "\(.*\)" para encontrar cualquier cadena que se encuentre
entre parntesis y se lo aplica sobre el texto "Ver (Fig. 1) y (Fig. 2)" se esperara que el
motor de bsqueda encuentre los textos "(Fig. 1)" y "(Fig. 2)", sin embargo, debido a esta
caracterstica, en su lugar encontrar el texto "(Fig. 1) y (Fig. 2)". Esto sucede porque el
asterisco le dice al motor de bsqueda que llene todos los espacios posibles entre los dos
parntesis. Para obtener el resultado deseado se debe utilizar el asterisco en conjunto con el
signo de pregunta de la siguiente forma: "\(.*?\)" Esto es equivalente a decirle al motor de
bsqueda que "Encuentre un parntesis de apertura y luego encuentre cualquier secuencia
de caracteres hasta que encuentre un parntesis de cierre".
Grupos annimos
Los grupos annimos se establecen cada vez que se encierra una expresin regular en
parntesis, por lo que la expresin "<([a-zA-Z]\w*?)>" define un grupo annimo que tendr
como resultado que el motor de bsqueda almacenar una referencia al texto que
corresponda a la expresin encerrada entre los parntesis.
La forma ms inmediata de utilizar los grupos que se definen es dentro de la misma
expresin regular, lo cual se realiza utilizando la barra inversa "\" seguida del nmero del
grupo al que se desea hacer referencia de la siguiente forma: "<([a-zA-Z]\w*?)>.*?</\1>"
Esta expresin regular encontrar tanto la cadena "Esta" como la cadena "prueba" en el
texto "Esta es una prueba" a pesar de que la expresin no contiene los literales "font" y
"B".
Otra forma de utilizar los grupos es en el lenguaje de programacin que se est utilizando.
Cada lenguaje tiene una forma distinta de acceder a los grupos. Los ejemplos enumerados a
continuacin utilizan las clases del .Net Framework, usando la sintxis de C# (la cual puede
fcilmente adaptarse a VB .Net o cualquier otro lenguaje del Framework o incluso Java o
JavaScript).
Para utilizar el motor de bsqueda del .Net Framework es necesario en primer lugar hacer
referencia al espacio de nombres System.Text.RegularExpressions. Luego es necesario
declarar una instancia de la clase Regex de la siguiente forma:
Regex _TagParser = new Regex("<([a-zA-Z]\w*?)>");
Luego asumiendo que el texto que se desea examinar con la expresin regular se encuentra
en la variable "sText" podemos recorrer todas las instancias encontradas de la siguiente
forma:
Luego se puede utilizar la propiedad Groups de la clase Match para traer el resultado de la
bsqueda:
foreach(Match CurrentMatch in _TagParser.Matches(sText)){
String sTagName = CurrentMatch. Groups[1].Value;
}
Grupos nominales
Los grupos nominales son aquellos a los que se les asigna un nombre, dentro de la
expresin regular para poder utilizarlos posteriormente. Esto se hace de forma diferente en
los distintos motores de bsqueda, a continuacin se explica como hacerlo en el motor del
.Net Framework.
Utilizando el ejemplo anterior es posible convertir "<([a-zA-Z]\w*?)>" en
"<(?<TagName>[a-zA-Z]\w*?)>" Para encontrar etiquetas HTML. Ntese el signo de
pregunta y el texto "TagName" encerrado entre parntesis triangulares, seguido de ste.
Para utilizar este ejemplo en el .Net Framework es posible utilizar el siguiente cdigo:
Regex _TagParser = new Regex("<(?<TagName>[a-zA-Z]\w*?)>");
foreach(Match CurrentMatch in _TagParser.Matches(sText)){
String sTagName = CurrentMatch. Groups["TagName"]. Value;
}
Es posible definir tantos grupos como sea necesario, de esta forma se puede definir algo
como: "<(?<TagName>[a-zA-Z]\w*?) ?(?<Attributes>.*?)>" para encontrar no solo el
nombre del tag HTML sino tambin sus atributos de la siguiente forma:
Regex
_TagParser
?(?<Attributes>.*?)>");
new
Regex("<(?<TagName>[a-zA-Z]\w*?)
Uso en java
El paquete java.util.regex esta formado por dos clases, la clase Matcher y la clasePattern y por
una excepcin, PatternSyntaxException.
La clase Pattern (segun la documentacion del jdk1.4) es la representacion compilada de una expresion
regular, o lo que es lo mismo, representa a la expresion regular, que en el
paquetejava.util.regex necesita estar compilada. En castellano significa patrn.
La clase Matcher es un tipo de objeto que se crea a partir de un patrn mediante la invocacin del
mtodo Pattern.matcher. Este objeto es el que nos permite realizar operaciones sobre la secuencia de
caracteres que queremos validar o la en la secuencia de caracteres en la que queremos buscar. En castellano
lo mas parecido a esto es la palabra encajador.
Por lo tanto tenemos patrones que deben ser compilados, a partir de estos creamos
objetosMatcher (encajadores) para poder realizar las operaciones sobre la cadena en cuestin.
Vamos con la clase Pattern, para crear un patrn necesitamos compilar una expresin regular, esto lo
conseguimos con el mtodo compile:
Ejemplos
El siguiente es un ejemplo del uso del mtodo replaceAll sobre una cadena. El ejemplo sustituye todas las
apariciones que concuerden con el patron "a*b" por la cadena "-".
// se importa el paquete java.util.regex
import java.util.regex.*;
public class EjemploReplaceAll{
public static void main(String args[]){
// compilamos el patron
Pattern patron = Pattern.compile("a*b");
// creamos el Matcher a partir del patron, la cadena como parametro
Matcher encaja = patron.matcher("aabmanoloaabmanoloabmanolob");
// invocamos el metodo replaceAll
String resultado = encaja.replaceAll("-");
System.out.println(resultado);
}
}
El siguiente ejemplo trata de validar una cadena que supuestamente contiene un email, lo hace con cuatro
comprobaciones, con un patrn cada una, la primera que no contenga como primer caracter una @ o un
punto, la segunda que no comience por www. , que contenga una y solo una @ y la cuarta que no contenga
caracteres ilegales:
import java.util.regex.*;
public class ValidacionEmail {
public static void main(String[] args) throws Exception {
String input = "www.?regular.com";
// comprueba que no empieze por punto o @
Pattern p = Pattern.compile("^.|^@");
Matcher m = p.matcher(input);
if (m.find())
System.err.println("Las direcciones email no empiezan por punto o @");
// comprueba que no empieze por www.
p = Pattern.compile("^www.");
m = p.matcher(input);
if (m.find())
System.out.println("Los emails no empiezan por www");
// comprueba que contenga @
p = Pattern.compile("@");
m = p.matcher(input);
if (!m.find())
System.out.println("La cadena no tiene arroba");
// comprueba que no contenga caracteres prohibidos
p = Pattern.compile("[^A-Za-z0-9.@_-~#]+");
m = p.matcher(input);
StringBuffer sb = new StringBuffer();
boolean resultado = m.find();
boolean caracteresIlegales = false;
while(resultado) {
caracteresIlegales = true;
m.appendReplacement(sb, "");
resultado = m.find();
}
// Aade el ultimo segmento de la entrada a la cadena
m.appendTail(sb);
input = sb.toString();
if (caracteresIlegales) {
System.out.println("La cadena contiene caracteres ilegales");
}
}
}
Conclusin
Las expresiones regulares vienen a tapar un hueco en el JDK de Sun que venia siendo solicitado desde hace
mucho tiempo. Con la inclusin de las expresiones regulares Java se convierte, en este tema, en un lenguaje
de programacin tan flexible como otros mas tradicionales en el tema de las expresiones regulares, Perl, Awk,
etc... Hasta ahora la unica opcin para conseguir un efecto parecido era el uso de StringTokenizer en
conjuncin con llamadas repetidas al mtodo charAt que produca un cdigo demasiado enrevesado. Las
expresiones regulares tienen un amplio abanico de posibilidades, principalmente para hacer bsquedas, para
sustituir ocurrencias y para comprobar la buena formacin de cadenas, como se ha visto en el ejemplo del
email.
Lo que viene a continuacin no es mas que la traduccin del la documentacin de una parte de la clase
Pattern. Para una referencia completa puede consultar la versin en ingles de Sun inc. sobre la clase Pattern
enhttp://java.sun.com/j2se/1.4/docs/api/java/util/regex/Pattern.html.
Expresion
Encaja con
Caracteres
x
El caracter x
El caracter
nn
mnn
xhh
uhhhh
Escape ('u001B')
cx
Intervalos de caracteres
[abc]
a, b, o c
[^abc]
[a-zA-Z]
[a-d[m-p]]
[a-z&&[def]]
La d, la e, o la f (interseccion)
[a-z&&[^bc]]
[a-z&&[^m-p]]
Intervalos de caracteres
predefinidos
.
Un numero: [0-9]
{upper}
Letras mayusculas:[A-Z]
{alpha}
Letras:[{lower}{upper}]
{digit}
{alnum}
Caracter alfanumerico:[{alpha}{digit}]
{punct}
Signos
de
puntuacion:
./:;<=>?@[]^_`{|}~
{graph}
{print}
{blank}
Un espacio o un tabulador: [ ]
{cntrl}
{xdigit}
{space}
Un espacio: [ x0Bf ]
uno
de !"#$%&'()*+,-
Limites
^
No es fin de palabra
Cuantificadores de cantidad
X?
X*
X+
X{n}
X, exactamente n veces
X(n,}
X{n,m}
XY
X seguido de Y
X|Y
XoY
(X)
X, como un grupo
, Escape, y entrecomillado
El caracter () sirve para preceder a expresiones con valores de escape tal y como se define en la tabla
anterior, asi como para entrecomillar caracteres que de otra manera serian interpretados como caracteres de
escape. De este modo la expresion representa a un unico y { representa a una llave.
Es un error usar un antes de cualquier caracter alfabetico que no corresponda a un caracter de escape, este
tipo de construcciones se reservan para extensiones de futuras versiones del lenguaje de expresiones
regulares. El caracter puede ser usado antes de un caracter no alfabetico a pesar de que el caracter sea parte
de una expresion que no sea de escape.
Terminadores de linea
Un terminador de linea es una secuencia de uno o dos caracteres que indica el final de una linea de la
secuencia de caracteres de entrada. Los siguientes son terminadores de linea:
El caracter de Nueva linea (line feed) (' '),
El caracter de retorno de carro seguido de una nueva linea (" "),
El caracter de retorno de carro unicamente (' '),
El caracter de nueva linea ('u0085'),
El caracter de separacin de linea ('u2028'), o
El caracter de separacion de parrafos ('u2029).
Si el modo UNIX_LINES esta activado entonces los unicos terminadores de linea reconocidos seran
caracteres de nueva linea.
La expresion regular . Representa a cualquier caracter excepto un terminador de linea a no ser que el
modo DOTALL sea especificado.
Grupos
Los grupos se numeran contando los parentesis abiertos de izquierda a derecha. En la expresion((A)(B(C))),
por ejemplo, hay cuatro de estos grupos:
1 ((A)(B(C)))
2 (A)
3 (B(C))
4 (C)
El grupo cero siempre es la expresin completa.