Tengo una tabla con ~ 500k filas; La columna varchar (255) UTF8 filename
contiene un nombre de archivo;
Estoy tratando de eliminar varios caracteres extraños del nombre de archivo, pensé que usaría una clase de caracteres: [^a-zA-Z0-9()_ .\-]
Ahora, ¿hay una función en MySQL que le permita reemplazar a través de una expresión regular ? Estoy buscando una funcionalidad similar a la función REPLACE (): a continuación se muestra un ejemplo simplificado:
SELECT REPLACE('stackowerflow', 'ower', 'over');
Output: "stackoverflow"
/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');
Output: "-tackover-low"
Sé acerca de REGEXP / RLIKE , pero esos solo comprueban si hay una coincidencia, no cuál es la coincidencia.
( Podría hacer un " SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]'
" desde un script PHP, hacer un preg_replace
y luego " UPDATE foo ... WHERE pkey_id=...
", pero parece un truco lento y feo de último recurso)
regexp_split
(función + procedimiento) ®exp_replace
, que se implementan con elREGEXP
operador. Para búsquedas simples, hará el truco. Puede encontrarlo aquí , así que esta es la forma con el código almacenado de MySQL, sin UDF. Si encuentra algunos errores, que no están cubiertos por limitaciones conocidas, no dude en abrir el problema.Respuestas:
Con MySQL 8.0+ puede usar la
REGEXP_REPLACE
función nativa .12.5.2 Expresiones regulares :
y soporte de expresiones regulares :
DBFiddle Demo
fuente
MySQL 8.0+ :
Puedes usar la
REGEXP_REPLACE
función nativa .Versiones anteriores:
Puede usar una función definida por el usuario ( UDF ) como mysql-udf-regexp .
fuente
Utilice MariaDB en su lugar. Tiene una funcion
Ver MariaDB docs y PCRE Mejoras de expresión regular
Tenga en cuenta que también puede usar la agrupación regexp (lo encontré muy útil):
devoluciones
fuente
UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\\1")
Esto elimina -2 de abcxyz-2 de una columna completa a la vez.Mi método de fuerza bruta para hacer que esto funcione fue simplemente:
mysqldump -u user -p database table > dump.sql
find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} \;
, obviamente, también hay otras expresiones regeulares perl que podría realizar en el archivo.mysqlimport -u user -p database table < dump.sql
Si desea asegurarse de que la cadena no esté en otra parte de su conjunto de datos, ejecute algunas expresiones regulares para asegurarse de que todas ocurran en un entorno similar. Tampoco es tan difícil crear una copia de seguridad antes de ejecutar un reemplazo, en caso de que destruya accidentalmente algo que pierde profundidad de información.
fuente
resolvemos este problema sin usar regex, esta consulta reemplaza solo la cadena de coincidencia exacta.
Ejemplo:
Después de ejecutar el resultado de la consulta:
fuente
Recientemente escribí una función MySQL para reemplazar cadenas usando expresiones regulares. Puedes encontrar mi publicación en la siguiente ubicación:
http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/
Aquí está el código de función:
Ejecución de ejemplo:
fuente
select regex_replace('.*(abc).*','\1','noabcde')
(devuelve 'noabcde', no 'abc').Me complace informar que, dado que se hizo esta pregunta, ¡ahora hay una respuesta satisfactoria! Eche un vistazo a este excelente paquete:
https://github.com/mysqludf/lib_mysqludf_preg
SQL de muestra:
Encontré el paquete de esta publicación de blog como vinculado a esta pregunta .
fuente
ACTUALIZACIÓN 2: Un conjunto útil de funciones regex que incluye REGEXP_REPLACE ahora se ha proporcionado en MySQL 8.0. Esto hace que la lectura sea innecesaria a menos que esté limitado a usar una versión anterior.
ACTUALIZACIÓN 1: Ahora he convertido esto en una publicación de blog: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html
Lo siguiente se expande sobre la función proporcionada por Rasika Godawatte, pero rastrea todas las subcadenas necesarias en lugar de solo probar caracteres individuales:
Manifestación
Demo de Rextester
Limitaciones
\1
,\2
etc.) para sustituir a los grupos de captura. Si se necesita esta funcionalidad, consulte esta respuesta que intenta proporcionar una solución alternativa actualizando la función para permitir una búsqueda y reemplazo secundario dentro de cada coincidencia encontrada (a expensas de una mayor complejidad).^
y / o$
se usa en el patrón, deben estar al principio y al final respectivamente, por ejemplo, patrones como los que(^start|end$)
no son compatibles.a.*?b.*
No se admite la combinación de coincidencia codiciosa y perezosa dentro de una sola expresión regular (p . Ej. ).Ejemplos de uso
La función se ha utilizado para responder las siguientes preguntas de StackOverflow:
fuente
Puede 'hacerlo' ... pero no es muy sabio ... esto es tan atrevido como lo intentaré ... en la medida en que RegEx completo lo respalde mucho mejor usando perl o similares.
fuente
Podemos usar la condición IF en la consulta SELECT de la siguiente manera:
Supongamos que para cualquier cosa con "ABC", "ABC1", "ABC2", "ABC3", ..., queremos reemplazar con "ABC" y luego usar la condición REGEXP e IF () en la consulta SELECT, podemos lograr esto .
Sintaxis:
Ejemplo:
fuente
Básicamente, el siguiente encuentra la primera coincidencia desde la izquierda y luego reemplaza todas las ocurrencias (probada en mysql-5.6)
Uso:
Implementación:
fuente
Creo que hay una manera fácil de lograr esto y está funcionando bien para mí.
Para SELECCIONAR filas usando REGEX
Para ACTUALIZAR filas usando REGEX
Referencia de REGEXP: https://www.geeksforgeeks.org/mysql-regular-expressions-regexp/
fuente