Ola, somos Arume

Desenvolvemos páxinas web, aplicacións para móbiles, capas de realidade aumentada e aplicacións para Facebook. Apaixónanos a informática e somos uns perfeccionistas incurables; por eso nos nosos proxectos utilizamos estándares.

tel. 625 519 694

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

Autenticarse

Rexistrarse. Esqueceches o teu contrasinal?

Etiquetas

Saltar as etiquetas

Subscríbete ás RSS

Estás en:

  • Inicio >
  • Blog >
  • Expresións regulares: conceptos básicos

Expresións regulares: conceptos básicos

21 Feb 2011 por Santi

Comentarios: 4

Expresións regulares

Á hora de traballar con cadeas de texto todas as linguaxes de programación nos proporcionan unhas útiles pero simples funcións comúns: buscar unha subcadea dentro dun texto, buscar a primeira aparición dun carácter, etc. Pero para un tratamento máis avanzado a maioría de linguaxes engaden librerías de funcións para traballar con expresións regulares. As expresións regulares proporciónannos moita máis potencia, pois mediante o uso duns simples patróns podemos especificar de forma concisa e flexible cadeas de texto para usar en procuras, reemplazamentos, etc.

Traballaremos coa sintaxe dunha das librerías máis coñecidas e utilizada na maioría das linguaxes de programación modernos: PCRE. Trátase dunha librería libre implementada en C e inspirada en interfaz externo de Perl (que, a pesar de denominarse "Expresións Regulares Compatibles con Perl" só é compatible cun subconxunto das expresións regulares de Perl).

Delimitadores

Os patróns da expresión regular deben ir sempre encerrados entre limitadores. Un limitador pode ser calquera carácter fóra de letras, números, barra invertida "\" ou espazo. Se o limitador aparece no patrón, será necesario "escapalo" usando a barra invertida.

Como norma xeral adoita usarse a barra "/" como delimitador, pero aconséllase cambialo se iso favorece a lexibilidade da expresión. Por exemplo, se queremos facer unha búsqueda dunha ruta de directorios como "/img/noticias/" poderiamos usar un patrón como /\/img\/noticias\//, pero é aconsellable substituír os demilitadores para non ter que "escapar" as barras que aparecen na cadea: #/img/noticias/#

Modificadores

Despois do limitador final pódense indicar modificadores que varían o procesamento do patrón. Os máis comúns son:

  • "i" Indica que as letras do patrón poden ser maiúsculas ou minúsculas
  • "m" Por defecto, os patróns son considerados como unha única liña. Este modificador indica que o patrón é multiliña, polo que os metacaracteres de principio e final de cadea ("^" e "$" respectivamente) tamén poden indicar adicionalmente principio e final de liña
  • "s" Indica que o carácter especial punto "." pode substituír a calquera carácter, incluíndo o salto de liña (por defecto, o punto non substitúe ao salto de liña)
  • "u" Indica que o patrón está codificado en UTF-8

Por exemplo, para indicar o patrón "Introdución a PCRE" sen considerar maiúsculas ou minúsculas e codificado en UTF-8 escribiriamos /introdución a pcre/iu

Metacaracteres

Certos carácteres son utilizados para indicar funcións especiais dentro do patrón, como alternativas ou repeticións, polo que deixan de ser denominados "literais" (xa non representan o seu valor natural). Estes carácteres son: \ . ^ $ [ ] ( ) | ? + * { }

Escape

O metacarácter máis importante é a barra invertida "\" pois como xa vimos serve para "escapar" os carácteres especiais se estes deben aparecer como literais dentro do patrón. Por exemplo, para escribir a cadea "\(img)\" dentro dun patrón escribiriamos /\\\(img\)\\/

Comodín

O punto "." é o metacarácter comodín, utilizado para indicar calquera carácter (menos os saltos de liña, a non ser que se inclúan os modificadores adecuados). Desta forma, se facemos unha búsqueda usando o patrón /c..d/ na cadea "a caldeira debuxada no candil", atoparemos "cald" e "cand".

Principio e final de cadea

Os carácteres "^" e "$" son usados para indicar o principio e final dunha cadea respectivamente. Como xa vimos, se o modificador de multiliña (m) está presente, indican, ademais, principio e final de liña. Por exemplo: /^img/ busca cadeas que empecen por "img", mentres que /^img/m busca cadeas que empecen por "img" ou que teñan "img" ó principio de calquera liña.

Clases de carácteres

Os corchetes "[ ]" úsanse para delimitar clases de carácteres. As clases de carácteres úsanse para indicar un carácter de entre varias posibilidades. Desta forma o patrón /c[ae]r/ pode atopar "car" en "aparcar" e "cer" en "cerca", pero non "caer" en "caeren". Hai que ter en conta que dentro dunha clase de carácteres cúmprense unhas cantas regras especiais en canto á sintaxe das expresións regulares:

  • Os metacaracteres (excepto "\") perden o seu significado e convértense en literais: por exemplo, o punto "." xa non é un comodín
  • Se o carácter "]" é o primeiro da clase considérase o literal "]", pero en calquera outra posición convértese no metacarácter "fin da clase de carácteres". Por exemplo /x[]abc]/ casa con "x]", "xa", "xb" e "xc"
  • Se o carácter "^" é o primeiro da clase convértese no metacarácter "negación", de forma que a clase indica calquera outro carácter que non apareza incluído nesa clase. Desta forma /[^pm]adre/ casa con "ladre", "Tadre" ou ata "!adre", pero nunca con "padre" e "madre".

O guión "-" úsase para indicar un rango de carácteres: por exemplo /[a-zA-Z0-9]/ casa con calquera letra ou número.

Agrupación

Os parénteses "( )" serven para agrupar carácteres, e adóitanse utilizar comunmente para indicar que outros metacaracteres, como cuantificadores e alternativa, afectan a un grupo de carácteres.

Alternativa

A barra "|" permítenos indicar unha de varias opcións. Desta forma /a|e/ casa con "a" ou "e". Utilízase comunmente ca agrupación, por exemplo /Son as 3 da (mañá|tarde)/ casa con "Son as 3 da mañá" ou con "Son as 3 da tarde"

Cuantificadores

Os seguintes metacaracteres permítennos controlar o número de veces que un carácter ou grupo de carácteres aparece nunha cadea de texto.

  • O signo de interrogación "?" permítenos definir un grupo como opcional. Por exemplo /Ago(sto)?/ casa con "Ago" ou con "Agosto"
  • O signo de suma "+" permítenos definir que un grupo atópase repetido 1 ou máis veces. Desta forma o patrón /(pa)+namericano/ podería utilizarse para atopar cadeas como "panamericano", "papanamericano", "papapanamericano", etc.
  • O asterisco "*" permítenos indicar un grupo que se atopa repetido 0 ou máis veces. Así, /(pa)*namericano/ atoparía as mesmas cadeas que o exemplo anterior, ademais da cadea "namericano"
  • As chaves "{ }" serven para cuantificar de forma máis exacta, de forma que nos permiten indicar exactamente o número de veces que pode aparecer repetido un grupo, xa sexa mediante un número exacto ou indicando un límite inferior e outro superior. Desta forma /(bla){3}/ casa só con "blablabla", mentres que /(bla){2,4}/ casa con "blabla", "blablabla" e "blablablabla".

Un exemplo

A expresión regular utilizada para validar se unha cadea é unha dirección de email válida podería ser por exemplo:

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

Nota sobre rendemento

A flexibilidade que nos ofrecen as funcións de tratamento de expresións regulares leva un alto custo en rendemento polo complexo procesamiento dos patróns, por iso é moi recomendable estudar ben o problema que estamos intentando resolver e sopesar se realmente é indispensable o uso de funcións de expresións regulares. Moitas veces ese mesmo problema pode ser resolto mediante o uso de funcións "clásicas" de manexo de cadeas de texto (strcmp, strstr, substr, ...) que pola súa simplicidade son computacionalmente moito máis rápidas.

Máis información

Páxina oficial de PCRE

Comentarios

4 comentarios. Comentar.

1. Anónimo o 05 Feb 2016 ás 21:31:20

Muchas gracias por tu aporte, muy claro.

2. Anónimo o 26 Mai 2016 ás 00:19:08

Excelente

3. Anónimo o 27 Ago 2016 ás 13:48:54

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

4. Maria Hilaria o 07 Set 2016 ás 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

Podes comentar poñendo calquera nome ou alcume, exceptuando os nomes de usuarios rexistrados. Máximo de 50 caracteres.

Comentar como usuario rexistrado

Rexistrarse. Esqueceches o teu contrasinal?