Eu tenho uma tabela com ~ 500k linhas; A coluna varchar (255) UTF8 filename
contém um nome de arquivo;
Estou tentando remover vários caracteres estranhos do nome do arquivo - pensei em usar uma classe de caracteres: [^a-zA-Z0-9()_ .\-]
Agora, existe uma função no MySQL que permite substituir por uma expressão regular ? Estou procurando uma funcionalidade semelhante à função REPLACE () - exemplo simplificado a seguir:
SELECT REPLACE('stackowerflow', 'ower', 'over');
Output: "stackoverflow"
/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');
Output: "-tackover-low"
Eu sei sobre o REGEXP / RLIKE , mas eles apenas verificam se há uma correspondência, não qual é a correspondência.
(Eu poderia fazer um " SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]'
" a partir de um script PHP, fazer um preg_replace
e depois " UPDATE foo ... WHERE pkey_id=...
", mas isso parece um hack lento e feio de último recurso)
regexp_split
(function + procedure) ®exp_replace
, que são implementados com oREGEXP
operador. Para pesquisas simples, ele fará o truque. Você pode encontrá-lo aqui - então, este é o caminho com o código armazenado do MySQL, sem UDF. Se você encontrar alguns erros, que não são cobertos por limitações conhecidas, fique à vontade para abrir o problema.Respostas:
Com o MySQL 8.0+, você pode usar a
REGEXP_REPLACE
função nativamente .12.5.2 Expressões regulares :
e suporte à expressão regular :
DBFiddle Demo
fonte
MySQL 8.0 ou superior :
Você pode usar a
REGEXP_REPLACE
função nativa .Versões mais antigas:
Você pode usar uma função definida pelo usuário ( UDF ) como mysql-udf-regexp .
fonte
Use MariaDB em vez disso. Tem uma função
Vejo documentos do MariaDB e aprimoramentos de expressão regular do PCRE
Observe que você também pode usar o agrupamento regexp (achei muito útil):
retorna
fonte
UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\\1")
Isso remove -2 de abcxyz-2 de uma coluna inteira de uma só vez.Meu método de força bruta para fazer isso funcionar era apenas:
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, existem outras expressões perl regeulares que você também pode executar no arquivo.mysqlimport -u user -p database table < dump.sql
Se você deseja garantir que a sequência não esteja em outro lugar no seu conjunto de dados, execute algumas expressões regulares para garantir que elas ocorram em um ambiente semelhante. Também não é tão difícil criar um backup antes de executar uma substituição, caso você destrua acidentalmente algo que perde a profundidade das informações.
fonte
resolvemos esse problema sem usar regex. Essa consulta substitui apenas a string de correspondência exata.
Exemplo:
Depois de executar o resultado da consulta:
fonte
Recentemente, escrevi uma função MySQL para substituir seqüências de caracteres usando expressões regulares. Você pode encontrar minha postagem no seguinte local:
http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/
Aqui está o código da função:
Execução de exemplo:
fonte
select regex_replace('.*(abc).*','\1','noabcde')
(retorna 'noabcde', não 'abc').Fico feliz em informar que, desde que essa pergunta foi feita, agora existe uma resposta satisfatória! Dê uma olhada neste pacote fantástico:
https://github.com/mysqludf/lib_mysqludf_preg
Exemplo de SQL:
Encontrei o pacote desta postagem do blog como vinculado a esta pergunta .
fonte
ATUALIZAÇÃO 2: Um conjunto útil de funções regex incluindo REGEXP_REPLACE foi fornecido no MySQL 8.0. Isso torna desnecessária a leitura, a menos que você seja obrigado a usar uma versão anterior.
ATUALIZAÇÃO 1: transformou isso em uma postagem de blog: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html
O seguinte expande a função fornecida por Rasika Godawatte, mas percorre todas as substrings necessárias, em vez de apenas testar caracteres únicos:
Demo
Rextester Demo
Limitações
\1
,\2
etc.) para substituir grupos de captura. Se essa funcionalidade for necessária, consulte esta resposta que tenta fornecer uma solução alternativa, atualizando a função para permitir uma localização secundária e substituição dentro de cada correspondência encontrada (às custas de maior complexidade).^
e / ou$
for usado no padrão, eles deverão estar no início e no final, respectivamente - por exemplo, padrões como os que(^start|end$)
não são suportados.a.*?b.*
) não é suportada.Exemplos de uso
A função foi usada para responder às seguintes perguntas sobre o StackOverflow:
fonte
Você 'pode' fazer isso ... mas não é muito sábio ... isso é tão ousado quanto tentarei ... na medida em que o RegEx completo ofereça suporte muito melhor ao usar perl ou algo semelhante.
fonte
Podemos usar a condição SE na consulta SELECT como abaixo:
Suponha que, para qualquer coisa com "ABC", "ABC1", "ABC2", "ABC3", ..., desejemos substituir por "ABC" e, em seguida, usando a condição REGEXP e IF () na consulta SELECT, podemos conseguir isso .
Sintaxe:
Exemplo:
fonte
O abaixo encontra basicamente a primeira correspondência da esquerda e substitui todas as ocorrências dela (testadas em mysql-5.6)
Uso:
Implementação:
fonte
Eu acho que existe uma maneira fácil de conseguir isso e está funcionando bem para mim.
Para selecionar linhas usando REGEX
Para atualizar linhas usando REGEX
Referência do REGEXP: https://www.geeksforgeeks.org/mysql-regular-expressions-regexp/
fonte