El blog de Juan Palómez

30 noviembre 2008

Extraer y reemplazar texto con expresiones regulares en MySQL

Filed under: programming, Uncategorized — Etiquetas: , , , , — thisisoneball @ 17:46

Extracting and replacing text with MySQL regular expressions

Entre las múltiples carencias de MySQL se encuentran (en parte) las expresiones regulares. Tiene el operador REGEXP que permite saber si una cadena casa con una expresión regular concreta, pero no permite extraer fragmentos de esa cadena ni reemplazar la cadena encontrada con otro texto.

Esta es una función para MySQL que hace precisamente eso valiéndose del propio operador REGEXP.

Es una chapuza rápida, probablemente no sea conveniente utilizarlo en determinados casos ya que debería ser bastante lenta (hace una llamada a REGEXP por cada subcadena contenida dentro de la cadena a buscar , por ejemplo, para buscar en ‘abc’, comprobaría la expresión regular con:

a

ab

abc

b

bc

c

Si llamas a esta función dentro del select o el where de una consulta con muchos registros puede ser realmente ineficiente. He añadido DETERMINISTIC ya que la función es determinista, y en algunos casos de esta manera se puede ahorrar bastante tiempo de proceso.

Hay otras opciones, como instalar UDFs de expresiones regulares. Las UDFs son código compilado y son mucho más rápidas. La ventaja de esta función es que es más fácil de instalar y es más portable.

Uso:

Devuelve la cadena más grande dentro de ‘cadena’ que coincida con ‘re’, por ejemplo

SELECT substring_regexp(‘jket5657twr’, ‘[0-9]+’, NULL) –> 5657

En este caso hay varias cadenas que coinciden con [0-9]+, por ejemplo 565, 5 , 657, … He decidido hacerlo de forma que devuelva la mayor de ellas.

Para sustituir, se pasa como parámetro la cadena de sustitución, en vez de NULL:

SELECT substring_regexp(‘jket5657twr’, ‘[0-9]+’, ‘HOLA’) –> jketHOLAtwr

Código:

DELIMITER $$

DROP FUNCTION IF EXISTS `substring_regexp` $$
CREATE FUNCTION `substring_regexp`(cadena text, re text, sustitucion text) RETURNS text CHARSET latin1 DETERMINISTIC
BEGIN

declare a, b, tam int;
declare subcadena, retorno text;

set tam = 0;
set retorno = '';
set a = 1;
inicio: WHILE a <= length(cadena) DO
	set b = a;
	final: WHILE b <= length(cadena) DO
		set subcadena = substring(cadena, a, b-a+1);
		if subcadena regexp concat('^', re, '$') and length(subcadena) > tam then
			set tam = length(subcadena);
			if sustitucion is null then
				set retorno = subcadena;
			else
				set retorno = replace(cadena, subcadena, sustitucion);
			end if;
		end if;
		set b = b+1;
	END WHILE final;
	set a = a+1;
END WHILE inicio;

return retorno;

END $$

DELIMITER ;

1 comentario »

  1. Gracias!!! muy buena funcion

    Comentarios por chato — 1 septiembre 2011 @ 19:47


RSS feed for comments on this post. TrackBack URI

Deja un comentario

Crea un blog o un sitio web gratuitos con WordPress.com.