Hola, somos Arume

Desarrollamos páginas web, aplicaciones para móviles, capas de realidad aumentada y aplicaciones para Facebook. Nos apasiona la informática y somos unos perfeccionistas incurables; por eso en nuestros proyectos utilizamos estándares.

tel. 625 519 694

Mendaña de Neyra, 34, 3º B, 15008, A Coruña

Autenticarse

Registrarse. ¿Has olvidado tu contraseña?

Etiquetas

Saltar las etiquetas

Suscríbete a las RSS

Estás en:

  • Inicio >
  • Blog >
  • Expresiones regulares: conceptos básicos

Expresiones regulares: conceptos básicos

21 Feb 2011 por Santi

Comentarios: 4

Expresiones regulares

A la hora de trabajar con cadenas de texto todos los lenguajes de programación nos proporcionan unas útiles pero simples funciones comunes: buscar una subcadena dentro de un texto, buscar la primera aparición de un carácter, etc. Pero para un tratamiento más avanzado la mayoría de lenguajes añaden librerías de funciones para trabajar con expresiones regulares. Las expresiones regulares nos proporcionan mucha más potencia, pues mediante el uso de unos simples patrones podemos especificar de forma concisa y flexible cadenas de texto para usar en búsquedas, reemplazamientos, etc.

Trabajaremos con la sintaxis de una de las librerías más conocidas y utilizada en la mayoría de los lenguajes de programación modernos: PCRE. Se trata de una librería libre implementada en C e inspirada en interfaz externo de Perl (que, a pesar de denominarse "Expresiones Regulares Compatibles con Perl" sólo es compatible con un subconjunto de las expresiones regulares de Perl).

Delimitadores

Los patrones de la expresión regular deben ir siempre encerrados entre limitadores. Un limitador puede ser cualquier carácter a excepción de letras, números, barra invertida "\" o espacio. Si el limitador aparece en el patrón, será necesario "escaparlo" usando la barra invertida.

Como norma general suele usarse la barra "/" como delimitador, pero se aconseja cambiarlo si ello favorece la legibilidad de la expresión. Por ejemplo, si queremos hacer una búsqueda de una ruta de directorios como "/img/noticias/" podríamos usar un patrón como /\/img\/noticias\//, pero es aconsejable sustituir los demilitadores para no tener que "escapar" las barras que aparecen en la cadena: #/img/noticias/#

Modificadores

Después del limitador final se pueden indicar modificadores que varían el procesamiento del patrón. Los más comunes son:

  • "i" Indica que las letras del patrón pueden ser mayúsculas o minúsculas
  • "m" Por defecto, los patrones son considerados como una única línea. Este modificador indica que el patrón es multilínea, por lo que los metacaracteres de principio y final de cadena ("^" y "$" respectivamente) también pueden indicar adicionalmente principio y final de línea
  • "s" Indica que el carácter especial punto "." puede reemplazar a cualquier carácter, incluyendo el salto de línea (por defecto, el punto no reemplaza al salto de línea)
  • "u" Indica que el patrón está codificado en UTF-8

Por ejemplo, para indicar el patrón "Introducción a PCRE" sin considerar mayúsculas o minúsculas y codificado en UTF-8 escribiríamos /introducción a pcre/iu

Metacaracteres

Ciertos caracteres son utilizados para indicar funciones especiales dentro del patrón, como alternativas o repeticiones, por lo que dejan de ser denominados "literales" (ya no representan su valor natural). Estos caracteres son: \ . ^ $ [ ] ( ) | ? + * { }

Escape

El metacarácter más importante es la barra invertida "\" pues como ya hemos visto sirve para "escapar" los caracteres especiales si estos deben aparecer como literales dentro del patrón. Por ejemplo, para escribir la cadena "\(img)\" dentro de un patrón escribiríamos /\\\(img\)\\/

Comodín

El punto "." es el metacarácter comodín, utilizado para indicar cualquier carácter (menos los saltos de línea, a no ser que se incluyan los modificadores adecuados). De esta forma, si hacemos una búsqueda usando el patrón /c..d/ en la cadena "la caldera dibujada en el cuadro", encontraremos "cald" y "cuad".

Principio y final de cadena

Los caracteres "^" y "$" son usados para indicar el principio y final de una cadena respectivamente. Como ya hemos visto, si el modificador de multilínea (m) está presente, indican, además, principio y final de línea. Por ejemplo: /^img/ busca cadenas que empiecen por "img", mientras que /^img/m busca cadenas que empiecen por "img" o que tengan "img" al principio de cualquier línea.

Clases de caracteres

Los corchetes "[ ]" se usan para delimitar clases de caracteres. Las clases de caracteres se usan para indicar un carácter de entre varias posibilidades. De esta forma el patrón /c[ae]r/ puede encontrar "car" en "aparcar" y "cer" en "cerdo", pero no "caer" en "caerse". Hay que tener en cuenta que dentro de una clase de caracteres se cumplen unas cuantas reglas especiales en cuanto a la sintaxis de las expresiones regulares:

  • Los metacaracteres (excepto "\") pierden su significado y se convierten en literales: por ejemplo, el punto "." ya no es un comodín
  • Si el carácter "]" es el primero de la clase se considera el literal "]", pero en cualquier otra posición se convierte en el metacarácter "fin de la clase de caracteres". Por ejemplo /x[]abc]/ casa con "x]", "xa", "xb" y "xc"
  • Si el carácter "^" es el primero de la clase se convierte en el metacarácter "negación", de forma que la clase indica cualquier otro carácter que no aparezca incluido en esa clase. De esta forma /[^pm]adre/ casa con "ladre", "Tadre" o incluso "!adre", pero nunca con "padre" y "madre".

El guión "-" se usa para indicar un rango de caracteres: por ejemplo /[a-zA-Z0-9]/ casa con cualquier letra o número.

Agrupación

Los paréntesis "( )" sirven para agrupar caracteres, y se suelen utilizar comúnmente para indicar que otros metacaracteres, como cuantificadores y alternativa, afectan a un grupo de caracteres.

Alternativa

La barra "|" nos permite indicar una de varias opciones. De esta forma /a|e/ casa con "a" o "e". Se utiliza comúnmente con la agrupación, por ejemplo /Son las 3 de la (mañana|tarde)/ casa con "Son las 3 de la mañana" o con "Son las 3 de la tarde"

Cuantificadores

Los siguientes metacaracteres nos permiten controlar el número de veces que un carácter o grupo de caracteres aparece en una cadena de texto.

  • El signo de interrogación "?" nos permite definir un grupo como opcional. Por ejemplo /Ago(sto)?/ casa con "Ago" o con "Agosto"
  • El signo de suma "+" nos permite definir que un grupo se encuentra repetido 1 o más veces. De esta forma el patrón /(pa)+namericano/ podría utilizarse para encontrar cadenas como "panamericano", "papanamericano", "papapanamericano", etc.
  • El asterisco "*" nos permite indicar un grupo que se encuentra repetido 0 o más veces. Así, /(pa)*namericano/ encontraría las mismas cadenas que el ejemplo anterior, además de la cadena "namericano"
  • Las llaves "{ }" sirven para cuantificar de forma más exacta, de forma que nos permiten indicar exactamente el número de veces que puede aparecer repetido un grupo, ya sea mediante un número exacto o indicando un límite inferior y otro superior. De esta forma /(bla){3}/ casa solo con "blablabla", mientras que /(bla){2,4}/ casa con "blabla", "blablabla" y "blablablabla".

Un ejemplo

La expresión regular utilizada para validar si una cadena es una dirección de email válida podría ser por ejemplo:

/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/i'

Nota sobre rendimiento

La flexibilidad que nos ofrecen las funciones de tratamiento de expresiones regulares conlleva un alto coste en rendimiento por el complejo procesamiento de los patrones, por ello es muy recomendable estudiar bien el problema que estamos intentando resolver y sopesar si realmente es indispensable el uso de funciones de expresiones regulares. Muchas veces ese mismo problema puede ser resuelto mediante el uso de funciones "clásicas" de manejo de cadenas de texto (strcmp, strstr, substr, ...) que por su simplicidad son computacionalmente mucho más rápidas.

Más información

Página oficial de PCRE

Comentarios

4 comentarios. Comentar.

1. Anónimo el 05 Feb 2016 a las 21:31:20

Muchas gracias por tu aporte, muy claro.

2. Anónimo el 26 May 2016 a las 00:19:08

Excelente

3. Anónimo el 27 Ago 2016 a las 13:48:54

me has sacado de una duda que tenía hace tiempo por tu forma clara de explicar. felicidades

4. Maria Hilaria el 07 Sep 2016 a las 17:53:46

Buenos dias!

si yo tengo una cabecera en mi archivo de entrada como la siguiente:

-----------------------------------------------------------------------------------------------------------

* Block Type = 96alum

* Chemistry = TAQMAN

* Experiment File Name = D:\Applied Biosystems\7500\experiments\2016-06.eds

* Experiment Run End Time = 2016-08-12 13:03:20 PM PDT

* Instrument Type = sds7500

* Passive Reference = ROX

[Results]

Well Sample Name Sample Type Target Name Task

-------------------------------------------------------------------

Como debo hacer para que la primera linea que lea e imprima sea la de los nombres de las columnas ("Well, Sample Name, ....)??

Comentar

Comentar de forma anónima

Puedes comentar poniendo cualquier nombre o apodo, exceptuando los nombres de usuarios registrados. Máximo de 50 caracteres.

Comentar como usuario registrado

Registrarse. ¿Has olvidado tu contraseña?