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 ;
Gracias!!! muy buena funcion
Comentarios por chato — 1 septiembre 2011 @ 19:47