SERVER142 ... con manos de programador

miércoles, julio 30, 2008

Expresiones Regulares en Mysql

Una expresión regular describe una serie de cadenas. La expresión regular más simple es aquella que no tiene caracteres especiales en su interior. Por ejemplo, la expresión regular hola concuerda con hola y nada más.

Una expresión regular no trivial usa ciertos constructores especiales, que pueden concordar más de en una cadena. Por ejemplo, la expresión regular hello|word concuerda tanto con la cadena hello como con la cadena word.

Un ejemplo más complicado: la expresión regular B[an]*s concuerda con las cadenas Bananas, Baaaaas, Bs, y cualquier otra cadena que comience con una B, termine con unas y contenga cualquier número de caracteres a o n entre ellas.

Una expresión regular para el operador REGEXP puede utilizar cualquiera de los siguientes caracteres especiales y constructores:

^

que concuerda con el inicio de la cadena.

mysql> SELECT 'fo\nfo' REGEXP '^fo$'; -> 0
mysql> SELECT 'fofo' REGEXP '^fo'; -> 1

$

que concuerda con el final de la cadena.

mysql> SELECT 'fo\no' REGEXP '^fo\no$'; -> 1
mysql> SELECT 'fo\no' REGEXP '^fo$'; -> 0

.

que concuerda con cualquier carácter (incluyendo el retorno de carro y la nueva línea).

mysql> SELECT 'fofo' REGEXP '^f.*$'; -> 1
mysql> SELECT 'fo\r\nfo' REGEXP '^f.*$'; -> 1

a*

que concuerda con cualquier secuencia de cero o más caracteres a.

mysql> SELECT 'Ban' REGEXP '^Ba*n'; -> 1
mysql> SELECT 'Baaan' REGEXP '^Ba*n'; -> 1
mysql> SELECT 'Bn' REGEXP '^Ba*n'; -> 1

a+

que concuerda con cualquier secuencia de uno o más caracteres a.

mysql> SELECT 'Ban' REGEXP '^Ba+n'; -> 1
mysql> SELECT 'Bn' REGEXP '^Ba+n'; -> 0

a?

que concuerda con cero o un carácter a.

mysql> SELECT 'Bn' REGEXP '^Ba?n'; -> 1
mysql> SELECT 'Ban' REGEXP '^Ba?n'; -> 1
mysql> SELECT 'Baan' REGEXP '^Ba?n'; -> 0

de|abc

que concuerda tanto con la secuencia de como con abc.

mysql> SELECT 'pi' REGEXP 'pi|apa'; -> 1
mysql> SELECT 'axe' REGEXP 'pi|apa'; -> 0
mysql> SELECT 'apa' REGEXP 'pi|apa'; -> 1
mysql> SELECT 'apa' REGEXP '^(pi|apa)$'; -> 1
mysql> SELECT 'pi' REGEXP '^(pi|apa)$'; -> 1
mysql> SELECT 'pix' REGEXP '^(pi|apa)$'; -> 0

(abc)*

que concuerda con cero o más instancias de la secuencia abc.

mysql> SELECT 'pi' REGEXP '^(pi)*$'; -> 1
mysql> SELECT 'pip' REGEXP '^(pi)*$'; -> 0
mysql> SELECT 'pipi' REGEXP '^(pi)*$'; -> 1

{1}, {2,3}

La notación {n} o {m,n} provee una manera más general de escribir expresiones regulares que concuerden con varias instancias del átomo anterior (o “pieza”) del patrón. m y n son enteros.

a*

Puede escribirse como a{0,}.

a+

Puede escribirse como a{1,}.

a?

Puede escribirse como a{0,1}.

Para ser más preciso, a{n} concuerda exactamente con n instancias de a. a{n,} concuerda con n o más instancias de a. a{m,n} concuerda con entre m y n (inclusive) instancias de a.

m y n deben estar en el rango desde 0 hasta RE_DUP_MAX (255 por defecto). Si se especifican tanto m como n, m debe ser menor o igual que n.


mysql> SELECT 'abcde' REGEXP 'a[bcd]{2}e'; -> 0
mysql> SELECT 'abcde' REGEXP 'a[bcd]{3}e'; -> 1
mysql> SELECT 'abcde' REGEXP 'a[bcd]{1,10}e'; -> 1

[a-dX], [^a-dX]

Concuerda con cualquier caracter que sea (o no sea, si se utiliza ^ ) uno de los siguientes: a, b, c, d o X. Un carácter - entre dos caracteres distintos forma un rango que concuerda con cualquier carácter entre el primero y el segundo. Por ejemplo, [0-9] concuerda con cualquier dígito decimal. Para incluir un carácter ] literal, debe estar precedido inmediatamente por un corchete abierto [. Para incluir un carácter - literal , debe estar al principio o al final. Cualquier carácter que no tenga un significado especial, concuerda sólo consigo mismo si está dentro de un par de [].


mysql> SELECT 'aXbc' REGEXP '[a-dXYZ]'; -> 1
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]$'; -> 0
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]+$'; -> 1
mysql> SELECT 'aXbc' REGEXP '^[^a-dXYZ]+$'; -> 0
mysql> SELECT 'gheis' REGEXP '^[^a-dXYZ]+$'; -> 1
mysql> SELECT 'gheisa' REGEXP '^[^a-dXYZ]+$'; -> 0

[.characters.]

Dentro de una expresión de corchetes (escrita usando [ y ]), concuerda con la sencuencia de caracteres expresada. characters es cualquier carácter simple o su nombre de carácter como newline. Se puede encontrar la lista completa de nombres de caracteres en el archivoregexp/cname.h.


mysql> SELECT '~' REGEXP '[[.~.]]'; -> 1
mysql> SELECT '~' REGEXP '[[.tilde.]]'; -> 1

[=character_class=]

Dentro de una expresión de corchetes (escrita usando [ y ]), [=character_class=] representa una clase de equivalencia. Concuerda con cualquier carácter con el mismo valor de comparación. Por ejemplo, si o y (+) son miembros de una clase equivalente, entonces [[=o=]], [[=(+)=]], y [o(+)] son todos sinónimos. Una clase equivalente no puede utilizarse como el final de un rango.

[:character_class:]

Dentro de una expresión de corchetes (escrita usando [ y ]), [:character_class:] representa una clase de caracteres que concuerda con todos los caracteres pertenecientes a esa clase. Los nombres de clases estándar son:

alnum Caracteres alfanumericos
alpha Caracteres Alfabéticos
blank Caracteres espacios en blanco
cntrl Caracteres de Control
digit Caracteres Dígitos
graph Caracteres gráficos
lower Caracteres alfabéticos en minúsculas
print Caracteres gráficos o espacios
punct Caracteres de puntación
space Espacio, tabulador, nueva línea y retorno de carro
upper Caracteres alfabéticos en mayúsculas
xdigit Caracteres dígitos en hexadecimal

Estos nombres representan las clases de caracteres definidas en ctype(3). Una localización particular pudiera proveer otros nombres de clases. Una clase de caracteres no se puede utilizar como final de un rango.


mysql> SELECT 'justalnums' REGEXP '[[:alnum:]]+'; -> 1
mysql> SELECT '!!' REGEXP '[[:alnum:]]+'; -> 0

[[:<:]], [[:>:]]

Estos marcadores representan limitadores de palabras. Concuerdan con el inicio y el final de palabras, respectivamente. Una palabra es una secuencia de caracteres de palabra que no son precedidos ni seguidos por caracteres de palabra. Un carácter de palabra es un carácter alfanumerico en la clase alnum o un guión bajo (_).


mysql> SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]'; -> 1
mysql> SELECT 'a xword a' REGEXP '[[:<:]]word[[:>:]]'; -> 0

Para utilizar en una expresión regular un carácter especial literalmente, precédalo con dos barras invertidas (\). El parser de MySQL interpreta las barras invertidas, y la biblioteca de expresiones regulares interpreta el resto. Por ejemplo, para concordar con la cadena 1+2, que contiene el carácter especial +, sólo la última de las siguientes expresiones regulares es correcta:

mysql> SELECT '1+2' REGEXP '1+2'; -> 0
mysql> SELECT '1+2' REGEXP '1\+2'; -> 0
mysql> SELECT '1+2' REGEXP '1\\+2'; -> 1