Underc0de

Programación Web => Back-end => Mensaje iniciado por: HckDrk en Noviembre 24, 2012, 02:11:59 AM

Título: Manual sencillo de Expresiones Regulares en PHP
Publicado por: HckDrk en Noviembre 24, 2012, 02:11:59 AM
Las expresiones regulares son una potente herramienta que nos permite contrastar un texto con un patrón de búsqueda. Esta tarea resulta fundamental en algunos programas, y en otros puede facilitarnos increíblemente el trabajo.

PHP permite dos tipos principales de funciones para expresiones regulares: las de tipo ereg (Expresiones regulares POSIX) y las de tipo preg (Compatibles con Perl). Son muy similares, aúnque las segundas llegan a ser algo más potentes.

Una expresión regular, consiste en comparar un patrón frente a un texto, para comprobar si el texto contiene lo especificado en el patrón.

Por poner un par de ejemplos:

Patrón: in
Coindicen:


Patrón: [mp]adre
Coindicen:


A continuación voy a repasar la sintaxis básica de una expresión regular

Sintaxis y metacaracteres

El punto

El punto representa cualquier caracter. Escribiendo un punto en un patrón querrás decir que ahí hay un caracter, cualquiera. Desde la A a la Z (en minúscula y mayúscula), del 0 al 9, o algún otro símbolo.

Ejemplos:

ca.a coincide con cana, cama, casa, caja, etc...
No coincide con casta ni caa

Principio y fin de cadena

Si queremos indicar al patrón qué es el principio de la cadena o qué es el final, debemos hacerlo con ^ para inicio y $ para final.

Ejemplos:

"^olivas" coincide con "olivas verdes", pero no con "quiero olivas"

Cuantificadores

Para indicar que cierto elemento del patrón va a repetirse un número indeterminado de veces, usaremos + o * . Usando + queremos decir que el elemento anterior aparece una o más veces. Usando * queremos decir que el elemento anterior aparece cero o más veces.

Ejemplos:

"gafas+" coincide con "gafassss" pero no con "gafa"
sin embargo
"clo*aca" coincide con "claca", "cloaca", "cloooooooaca", etc..
Si lo que queremos indicar al patrón es que un elemento puede que esté (una vez) o puede que no, lo haremos con el interrogante de la siguiente forma:
"coches?" coincide con "coche" y con "coches"

Para definir la cantidad de veces que va a repetirse el elemento, tendremos que hacer uso de las llaves: { }, indicando en su interior el intervalo, o la cantidad exacta de veces que va a repetirse.

Ejemplos:

"abc{4}" coincide con "abcccc", pero no con "abc" ni "abcc", etc...
"abc{1,3}" coincide con "abc", "abcc", "abccc", pero no con "abcccc"

Si un parámetro queda vacío, significa "un número indeterminado". Por ejemplo: "x{5,}" significa que la x ha de repetirse 5 veces, o más.

Rangos

Los corchetes [] incluidos en un patrón permiten especificar el rango de caracteres válidos a comparar. Basta que exista cualquiera de ellos para que se de la condición. Dentro de ellos pondremos cualquier cantidad de caracteres, uno a continuación del otro; o un rango del abecedario o de los números enteros del 0 al 9.

Ejemplos:

"c[ao]sa" coincide con "casa" y con "cosa"
"[a-f]" coincide con todos los caracteres alfabéticos de la "a" a la "f"
"[0-9][2-6][ANR]" coincide con "12A", "35N", "84R", etc..
pero no con "21A", ni "33L", ni "3A", etc...

Dentro de los corchetes, hay que tener en cuenta que el símbolo ^ ya no significa inicio, sinó que es un negador, es decir: "[^a-Z]" coincidirá con cualquier texto que NO tenga ningún caracter alfabético (ni minúsculas ni mayúsculas), y "^@ " coincide con cualquier caracter excepto "@" y "espacio"

Alternancia


Para alternar entre varias opciones, usaremos el símbolo | (barra vertical, en los teclados suele ser "Alt Gr + 1″). Con este mecanismo haremos un disyuntor, que nos permitirá dar varias opciones. Si una de ellas coincide, el patrón será cierto.

Ejemplos:
"aleman(ia|es)" coincide con "alemania" y con "alemanes"
"(norte|sur|este|oeste)" coincide con cualquiera de los puntos cardinales.

Agrupadores

Los paréntesis nos sirven para agrupar un subconjunto. Como hemos visto en el ejemplo anterior, nos es útil para definir la alternancia, pero agrupar un subpatrón nos permite trabajar con él como si fuera un único elemento.

Ejemplos:

"(abc)+" coincide con "abc", "abcabc", "abcabcabc", etc
"ca(sca)?da" coincide con "cascada" y con "cada"

Escapar caracteres

Si por ejemplo quisiéramos que en el patrón hubiese un punto, o un símbolo asterisco, sin que se interprete como metacaracter, tendremos que "escaparlo". Esto se hace poniendo una barra invertida justo antes: \. o \*
Esto puede hacerse con cualquier caracter que quieras introducir de forma literal, y no interpretada.

Las funciones

Una vez tenemos clara la sintaxis, nos pondremos manos a la obra con el código. En este caso usaremos las funciones que nos proporciona PHP, aúnque la sintaxis es común a muchos lenguajes.

Funciones tipo POSIX

Existen seis funciones de este tipo, que son las siguientes:

ereg(). Devuelve true si se cumple el patrón, o false si no se cumple.
eregi(). Igual que ereg(), pero sin distinguir mayúsculas y minúsculas
ereg_replace(). Usando la potencia de las expresiones regulares, permite modificar una cadena de texto.
eregi_replace(). Igual que la anterior, sin distinguir minúsculas y mayúsculas.
split(). Divide una cadena en un array, según un patrón REGEX. Hace la misma tarea que la función explode, pero indicando una expresión regular como separador.
spliti(). Igual que el anterior, sin diferenciar minúscula y mayúscula.

Funciones tipo PCRE

Estas funciones son un poco más complejas, y consecuentemente más potentes. La diferencia más significativa en cuanto a sintaxis es que el patrón deberá estar delimitado por dos caracteres. Usualmente se usan barras ( / ), aunque podemos usar cualquier símbolo, como ( # ), sobretodo en un patrón que contenga barras. Otra diferencia importante son los modificadores.

preg_match(). Chequea el patrón en una cadena alfanumérica. Devuelve true si coincide, o false en caso contrario. Además captura las coincidencias en un array.
preg_match_all(). Igual que preg_match, pero almacenando todas las subcadenas que coincidan con el patrón (no sólo una como es el caso de preg_match)
preg_replace(). Nos permite reemplazar textos mediante expresiones regulares. Los argumentos pueden ser arrays, con lo que se realiza más de una sustitución con una sola función.
preg_split(). Separa la cadena dada mediante una expresión regular.
preg_grep(). Busca el patrón dentro de un array, y devuelve otro array con las ocurrencias.

Ejemplos prácticos

A continuación muestro algunos ejemplos de uso de estas funciones:
Uso sencillo de preg_match.

Código (php) [Seleccionar]
<?php
// Este código lee la variable $documento (HTML), y encuentra un numero en negrita
$documento '<h1>Numero</h1> <p>El numero es <strong>720</strong>, bla bla bla</p>';
preg_match("#<strong>([0-9]+)</strong>#is",$documento,$num);
$numero $num[1];
 
echo 
$numero// Devuelve 720
?>


Uso de la referencia hacia atrás en preg_match_all

Código (php) [Seleccionar]
<?php
// El \\2 es un ejemplo de referencia hacia atrás. Este le dice a pcre
// que debe buscar el segundo conjunto de paréntesis en la expresión
// regular misma, que sería ([\w]+) en este caso. La barra invertida
// extra es requerida ya que la cadena se encuentra entre comillas
// dobles.
$html "<b>texto en negrilla</b><a href=hola.html>haga clic aquí</a>";
 
preg_match_all("/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/"$html$coincidenciasPREG_SET_ORDER);
 
foreach (
$coincidencias as $val) {
    echo 
"coincidencia: " $val[0] . "\n";
    echo 
"parte 1: " $val[1] . "\n";
    echo 
"parte 2: " $val[3] . "\n";
    echo 
"parte 3: " $val[4] . "\n\n";
}
?>


Simple comprobación con el patrón de IP

Código (php) [Seleccionar]
<?php
// Funcion que comprueba si el dato pasado es una IP correcta
function ipValida($ip){
   if(!
eregi("^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"$ip))
      return 
false;
   
   
$tmp explode("."$ip);
 
      foreach(
$tmp as $sub){
              
$sub $sub 1;
                if(
$sub<|| $sub>256) return false;
      }
 
   return 
true;
}
?>


Referencias

Expresiones Regulares (Ignside) (http://www.ignside.net/man/php/regex.php), lectura muy recomendada
Funcionamiento interno de los RegEx (Inglés) (http://perl.plover.com/Regex/article.html), si tienes curiosidad y entiendes inglés.
Librería de expresiones regulares ya hechas (http://regexlib.com/), para no reinventar la rueda.
Referencia sintaxis de funciones PCRE (http://es.php.net/manual/es/reference.pcre.pattern.syntax.php) del manual oficial.
Referencia Modificadores (http://es.php.net/manual/es/reference.pcre.pattern.modifiers.php) del manual oficial.
Expresión Regular (http://es.wikipedia.org/wiki/Expresi%C3%B3n_regular) en Wikipedia
Tutorial de Expresiones Regulares (http://www.wikilearning.com/introduccion_a_las_expresiones_regulares-wkc-419.htm) en Wikilearning


Fuente (http://boozox.net/php/manual-completo-y-sencillo-de-expresiones-regulares-en-php/)
Título: Re:Manual sencillo de Expresiones Regulares en PHP
Publicado por: ~ Yoya ~ en Noviembre 24, 2012, 02:19:15 AM
Una pequeña aclaración y muy importante, recordar que el punto  coincide con todo excepto con salto de lineas. Y bueno, en lo personal no recomiendo utilizarlo, preferiblemente es mejor hacer un patrón mas especifico.

Saludos.
Título: Re:Manual sencillo de Expresiones Regulares en PHP
Publicado por: Alex en Noviembre 25, 2012, 10:52:21 PM
lo agrego al indice de temas, se agradece el aporte!

saludos!