Ich habe eine Tabelle mit ~ 500k Zeilen; Die Spalte varchar (255) UTF8 filename
enthält einen Dateinamen.
Ich versuche, verschiedene seltsame Zeichen aus dem Dateinamen zu entfernen - dachte, ich würde eine Zeichenklasse verwenden: [^a-zA-Z0-9()_ .\-]
Gibt es in MySQL eine Funktion, mit der Sie durch einen regulären Ausdruck ersetzen können ? Ich suche nach einer ähnlichen Funktionalität wie die Funktion REPLACE () - es folgt ein vereinfachtes Beispiel:
SELECT REPLACE('stackowerflow', 'ower', 'over');
Output: "stackoverflow"
/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');
Output: "-tackover-low"
Ich weiß über REGEXP / RLIKE Bescheid , aber diese prüfen nur, ob es eine Übereinstimmung gibt, nicht, was die Übereinstimmung ist.
(Ich könnte ein " SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]'
" aus einem PHP-Skript machen, ein " preg_replace
und dann" UPDATE foo ... WHERE pkey_id=...
"machen, aber das sieht aus wie ein langsamer und hässlicher Hack der letzten Instanz)
regexp_split
(Funktion + Prozedur) & erstelltregexp_replace
, die mitREGEXP
Operator implementiert werden. Für einfache Suchvorgänge reicht es aus. Sie finden es vielleicht hier - also ist dies der Weg mit gespeichertem MySQL-Code, ohne UDF. Wenn Sie Fehler finden, die nicht durch bekannte Einschränkungen abgedeckt sind, können Sie das Problem gerne öffnen.Antworten:
Mit MySQL 8.0+ können Sie die native
REGEXP_REPLACE
Funktion verwenden.12.5.2 Reguläre Ausdrücke :
und Unterstützung für reguläre Ausdrücke :
DBFiddle Demo
quelle
MySQL 8.0+ :
Sie können die native
REGEXP_REPLACE
Funktion verwenden.Ältere Versionen:
Sie können eine benutzerdefinierte Funktion ( UDF ) wie mysql-udf-regexp verwenden .
quelle
Verwenden Sie stattdessen MariaDB. Es hat eine Funktion
Siehe MariaDB-Dokumente und PCRE-Verbesserungen für reguläre Ausdrücke
Beachten Sie, dass Sie auch die Regexp-Gruppierung verwenden können (ich fand das sehr nützlich):
kehrt zurück
quelle
UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\\1")
Dadurch wird -2 aus abcxyz-2 auf einmal aus einer ganzen Spalte entfernt.Meine Brute-Force-Methode, um dies zum Laufen zu bringen, war nur:
mysqldump -u user -p database table > dump.sql
find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} \;
einiger Muster - Es gibt offensichtlich andere reguläre Perl-Ausdrücke, die Sie auch für die Datei ausführen können.mysqlimport -u user -p database table < dump.sql
Wenn Sie sicherstellen möchten, dass sich die Zeichenfolge nicht an einer anderen Stelle in Ihrem Dataset befindet, führen Sie einige reguläre Ausdrücke aus, um sicherzustellen, dass sie alle in einer ähnlichen Umgebung vorkommen. Es ist auch nicht so schwierig, ein Backup zu erstellen, bevor Sie einen Ersatz ausführen, falls Sie versehentlich etwas zerstören, das an Informationstiefe verliert.
quelle
Wir lösen dieses Problem ohne Verwendung von Regex. Diese Abfrage ersetzt nur die exakte Übereinstimmungszeichenfolge.
Beispiel:
Nach dem Ausführen des Abfrageergebnisses:
quelle
Ich habe kürzlich eine MySQL-Funktion geschrieben, um Zeichenfolgen durch reguläre Ausdrücke zu ersetzen. Sie finden meinen Beitrag an folgender Stelle:
http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/
Hier ist der Funktionscode:
Beispielausführung:
quelle
select regex_replace('.*(abc).*','\1','noabcde')
(gibt 'noabcde' zurück, nicht 'abc').Ich freue mich, Ihnen mitteilen zu können, dass es seit der Beantwortung dieser Frage eine zufriedenstellende Antwort gibt! Schauen Sie sich dieses tolle Paket an:
https://github.com/mysqludf/lib_mysqludf_preg
Beispiel-SQL:
Ich habe das Paket aus diesem Blog-Beitrag gefunden, das auf diese Frage verlinkt ist .
quelle
UPDATE 2: In MySQL 8.0 wurde jetzt ein nützlicher Satz von Regex-Funktionen bereitgestellt, einschließlich REGEXP_REPLACE . Dies macht das Lesen unnötig, es sei denn, Sie müssen eine frühere Version verwenden.
UPDATE 1: Habe dies jetzt zu einem Blog-Beitrag gemacht: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html
Das Folgende erweitert die von Rasika Godawatte bereitgestellte Funktion, durchläuft jedoch alle erforderlichen Teilzeichenfolgen, anstatt nur einzelne Zeichen zu testen:
Demo
Rextester Demo
Einschränkungen
\1
,\2
etc.) erfassen Gruppen zu ersetzen. Wenn diese Funktionalität benötigt wird, lesen Sie bitte diese Antwort die versucht, eine Problemumgehung bereitzustellen, indem Sie die Funktion aktualisieren, um ein sekundäres Suchen und Ersetzen innerhalb jeder gefundenen Übereinstimmung zu ermöglichen (auf Kosten einer erhöhten Komplexität).^
und / oder$
im Muster verwendet wird, müssen sie ganz am Anfang bzw. am Ende stehen - z. B. Muster,(^start|end$)
die nicht unterstützt werden.a.*?b.*
) wird nicht unterstützt.Anwendungsbeispiele
Die Funktion wurde verwendet, um die folgenden StackOverflow-Fragen zu beantworten:
quelle
Sie können es tun ... aber es ist nicht sehr klug ... das ist ungefähr so gewagt, wie ich es versuchen werde ... soweit die vollständige RegEx-Unterstützung Ihre viel bessere Verwendung von Perl oder dergleichen unterstützt.
quelle
Wir können die IF-Bedingung in der SELECT-Abfrage wie folgt verwenden:
Angenommen, für alles mit "ABC", "ABC1", "ABC2", "ABC3", ... möchten wir durch "ABC" ersetzen und dann die Bedingungen REGEXP und IF () in der SELECT-Abfrage verwenden, um dies zu erreichen .
Syntax:
Beispiel:
quelle
Die folgende findet im Grunde die erste Übereinstimmung von links und ersetzt dann alle Vorkommen davon (getestet in MySQL-5.6).
Verwendungszweck:
Implementierung:
quelle
Ich denke, es gibt einen einfachen Weg, dies zu erreichen, und es funktioniert gut für mich.
Zeilen mit REGEX AUSWÄHLEN
Zeilen mit REGEX AKTUALISIEREN
REGEXP-Referenz: https://www.geeksforgeeks.org/mysql-regular-expressions-regexp/
quelle