domingo, 25 de diciembre de 2011

[PHP] Sintaxis básica de una expresión regular

Un articulo bastante interesante de un manual llamado "Generacion de Websites dinamicos usando PHP" el cual espero les sirva a muchos como a mi:

Los símbolos especiales “^” y “$” se usan para matchear el principio y el final de un string respectivamente.

Por ejemplo:
“^el” Matchea strings que empiezan con “el”
“colorin colorado$” Matchea strings que terminan en “colorin colorado”
“^abc$” String que empieza y termina en abc, es decir solo “abc” matchea
“abc” Un string que contiene “abc” por ejemplo “abc” ,”gfabc”, “algoabcfgeh”, etc...

Los símbolos “*” , “+” y “?” denotan la cantidad de veces que un caracter o una secuencia de caracteres puede ocurrir. Y denotan 0 o más, una o más y cero o una ocurrencias respectivamente.

Por ejemplo:
“ab*” Matchea strings que contienen una “a” seguida de cero o mas “b”
Ej: “a”, “ab”, “cabbbb”, etc
“ab+” Matchea strings que contienen una “a” seguida de una o mas “b”
“ab?” Matchea strings que contienen una “a” seguida o no de una “b” pero no mas de 1.
“a?b+$” Matchea “a” seguida de una o mas “b” terminando el string.

Para indicar rangos de ocurrencias distintas pueden especificarse la cantidad máxima y mínima de ocurrencias usando llaves de la forma {min,max}

“ab{2}” Una “a” seguida de exactamente 2 “b”
“ab{2,}” Una “a” seguida de 2 o mas “b”
“ab{3,5}” Una “a” seguida de 3 a 5 “b” (“abbb”, “abbbb”, ”abbbbb”)

Es obligatorio especificar el primer número del rango pero no el segundo. De esta forma + equivale a {1,}. * equivale a {0,} y ? equivale a {0,1}

Para cuantificar una secuencia de caracteres basta con ponerla entre paréntesis.

“a(bc)*” Matchea una “a” seguida de cero o mas ocurrencias de “bc” ej: “abcbcbc”
El símbolo “|” funciona como operador “or
“hola|Hola” Matchea strings que contienen “hola” u “Hola”
“(b|cd)ef” Strings que contienen “bef” o “cdef”
“(a|b)*c” Secuencias de “a” o “b” y que termina en “c”
El carácter “.” matchea a cualquier otro caracter.
“a.[0-9]” Matchea “a” seguido de cualquier caracter y un dígito.
“^.{3}$” Cualquier string de exactamente 3 caracteres.

Los corchetes se usan para indicar que caracteres son validos en una posición única del string.
“[ab]” Matchea strings que contienen “a” o “b”
“[a-d]” Matchea strings que contienen “a”, “b” , “c” o “d”
“^[a-zA-Z]” Strings que comienzan con una letra.
“[0-9]%” Un dígito seguido de un signo %

También puede usarse una lista de caracteres que no se desean agregando el símbolo “^” dentro de los corchetes, no confundir con “^” afuera de los corchetes que matchea el principio de línea.
“[^abg]” Strings que NO contienen “a” , “b” o “g”
“[^0-9]” Strings que no contienen dígitos

Los caracteres “^.[$()|*+?{\” deben escaparse si forman parte de lo que se quiere buscar con una barra invertida adelante. Esto no es válido dentro de los corchetes donde todos los caracteres no tienen significado especial.

Ejemplos:
Validar una suma monetaria en formato: “10000.00”, “10,000.00” .,“10000” o “10,000” es decir con o sin
centavos y con o sin una coma separando tres dígitos.
^[1-9][0-9]*$
Esto valida cualquier número que no empieza con cero, lo malo es que “0” no pasa el test. Entonces:
^(0|[1-9][0-9]*)$
Un cero o cualquier número que no empieza con cero. Aceptemos también un posible signo menos delante.
^(0|-?[1-9][0-9]*)$
O sea cero o cualquier número con un posible signo “-“ delante.
En realidad podemos admitir que un número empiece con cero para una cantidad monetaria y supongamos
que el signo “-“ no tiene sentido, agreguemos la posibilidad de decimales:
^[0-9]+(\.[0-9]+)?$
Si viene un “.” debe esta seguido de un dígito, 10 es válido pero “10.” no
Especifiquemos uno o dos dígitos decimales:
^[0-9]+(\.[0-9]{1,2})?$
Ahora tenemos que agregar las comas para separar de a miles.
^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{1,2})?$
O sea un conjunto de 1 a 3 dígitos seguido de uno más conjuntos de “,” seguido de tres dígitos. Ahora
hagamos que la coma sea opcional.
^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(\.[0-9]{1,2})?$
Y de esta forma podemos validar números con los 4 formatos validos en una sola expresión