J'ai une table avec environ 500 000 lignes; varchar (255) La colonne UTF8 filename
contient un nom de fichier;
J'essaie de retirer divers caractères étranges du nom de fichier - je pensais utiliser une classe de caractères: [^a-zA-Z0-9()_ .\-]
Maintenant, y a-t-il une fonction dans MySQL qui vous permet de remplacer via une expression régulière ? Je recherche une fonctionnalité similaire à la fonction REPLACE () - un exemple simplifié suit:
SELECT REPLACE('stackowerflow', 'ower', 'over');
Output: "stackoverflow"
/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');
Output: "-tackover-low"
Je connais REGEXP / RLIKE , mais ceux-ci vérifient seulement s'il y a une correspondance, pas ce que la correspondance est.
(Je pourrais faire un " SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]'
" à partir d'un script PHP, faire un preg_replace
puis " UPDATE foo ... WHERE pkey_id=...
", mais cela ressemble à un hack lent et laid de dernier recours)
regexp_split
(fonction + procédure) ®exp_replace
, qui sont implémentés avec l'REGEXP
opérateur. Pour les recherches simples, il fera l'affaire. Vous pouvez le trouver ici - c'est donc le cas avec le code stocké MySQL, sans UDF. Si vous trouvez des bogues qui ne sont pas couverts par les limitations connues, n'hésitez pas à ouvrir le problème.Réponses:
Avec MySQL 8.0+, vous pouvez utiliser la
REGEXP_REPLACE
fonction native .12.5.2 Expressions régulières :
et prise en charge des expressions régulières :
DBFiddle Demo
la source
MySQL 8.0+ :
Vous pouvez utiliser le natif
REGEXP_REPLACE
fonction .Versions plus anciennes:
Vous pouvez utiliser une fonction définie par l'utilisateur ( UDF ) comme mysql-udf-regexp .
la source
Utilisez plutôt MariaDB. Il a une fonction
Voir les documents MariaDB et les améliorations des expressions régulières PCRE
Notez que vous pouvez également utiliser le regroupement d'expressions rationnelles (j'ai trouvé cela très utile):
Retour
la source
UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\\1")
Cela supprime -2 de abcxyz-2 d'une colonne entière à la fois.Ma méthode de force brute pour que cela fonctionne était simplement:
mysqldump -u user -p database table > dump.sql
find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} \;
, Il y a évidemment d'autres expressions regeular perl que vous pouvez également effectuer sur le fichier.mysqlimport -u user -p database table < dump.sql
Si vous voulez vous assurer que la chaîne n'est pas ailleurs dans votre ensemble de données, exécutez quelques expressions régulières pour vous assurer qu'elles se produisent toutes dans un environnement similaire. Il n'est également pas si difficile de créer une sauvegarde avant d'exécuter un remplacement, au cas où vous détruiriez accidentellement quelque chose qui perd de la profondeur des informations.
la source
nous résolvons ce problème sans utiliser l'expression régulière. Cette requête remplace uniquement la chaîne de correspondance exacte.
Exemple:
Après avoir exécuté le résultat de la requête:
la source
J'ai récemment écrit une fonction MySQL pour remplacer les chaînes à l'aide d'expressions régulières. Vous pouvez trouver mon message à l'emplacement suivant:
http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/
Voici le code de fonction:
Exemple d'exécution:
la source
select regex_replace('.*(abc).*','\1','noabcde')
(renvoie 'noabcde', pas 'abc').Je suis heureux d'annoncer que depuis que cette question a été posée, il y a maintenant une réponse satisfaisante! Jetez un œil à ce formidable package:
https://github.com/mysqludf/lib_mysqludf_preg
Exemple de SQL:
J'ai trouvé le package de ce billet de blog lié à cette question .
la source
MISE À JOUR 2: Un ensemble utile de fonctions d' expression régulière, y compris REGEXP_REPLACE, a maintenant été fourni dans MySQL 8.0. Cela rend la lecture inutile sauf si vous êtes contraint d'utiliser une version antérieure.
MISE À JOUR 1: Je l'ai maintenant transformé en article de blog: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html
Ce qui suit développe la fonction fournie par Rasika Godawatte mais parcourt toutes les sous-chaînes nécessaires plutôt que de simplement tester des caractères uniques:
Démo
Démo Rextester
Limites
\1
,\2
etc.) pour remplacer les groupes de capture. Si cette fonctionnalité est nécessaire, veuillez voir cette réponse qui tente de fournir une solution de contournement en mettant à jour la fonction pour permettre une recherche et un remplacement secondaires dans chaque correspondance trouvée (au détriment d'une complexité accrue).^
et / ou$
sont utilisés dans le modèle, ils doivent être respectivement au tout début et à la toute fin - par exemple, les modèles tels que(^start|end$)
ne sont pas pris en charge.a.*?b.*
) n'est pas prise en charge.Exemples d'utilisation
La fonction a été utilisée pour répondre aux questions StackOverflow suivantes:
la source
Vous 'pouvez' le faire ... mais ce n'est pas très sage ... c'est à peu près aussi audacieux que j'essaierai ... dans la mesure où RegEx complet prend en charge votre bien meilleure utilisation de perl ou similaire.
la source
Nous pouvons utiliser la condition IF dans la requête SELECT comme ci-dessous:
Supposons que pour tout ce qui a "ABC", "ABC1", "ABC2", "ABC3", ..., nous voulons remplacer par "ABC" puis en utilisant la condition REGEXP et IF () dans la requête SELECT, nous pouvons y parvenir .
Syntaxe:
Exemple:
la source
Celui ci-dessous trouve essentiellement la première correspondance à partir de la gauche, puis en remplace toutes les occurrences (testé dans mysql-5.6).
Usage:
La mise en oeuvre:
la source
Je pense qu'il existe un moyen facile d'y parvenir et cela fonctionne bien pour moi.
Pour sélectionner des lignes à l'aide de REGEX
Pour METTRE À JOUR des lignes à l'aide de REGEX
Référence REGEXP: https://www.geeksforgeeks.org/mysql-regular-expressions-regexp/
la source