570

〜50万行のテーブルがあります。varchar(255) UTF8 列filenameにはファイル名が含まれます。

ファイル名からさまざまな奇妙な文字を取り除こうとしています-文字クラスを使用すると思いました:[^a-zA-Z0-9()_ .\-]

さて、MySQL に正規表現で置換できる関数はありますか? REPLACE() 関数と同様の機能を探しています-簡単な例は次のとおりです。

SELECT REPLACE('stackowerflow', 'ower', 'over');

Output: "stackoverflow"

/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-'); 

Output: "-tackover-low"

REGEXP/RLIKEについては知っていますが、それらは一致があるかどうかのみを確認し、一致が何であるかは確認しません。

( PHPSELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .\-]'スクリプトpreg_replaceから「UPDATE foo ... WHERE pkey_id=..._

4

13 に答える 13

160

MySQL 8.0+ :

ネイティブREGEXP_REPLACE機能を使用できます。

古いバージョン:

mysql-udf-regexp のようなユーザー定義関数 ( UDF )を使用できます。

于 2009-06-12T14:16:44.620 に答える
150

MariaDB または MySQL 8.0 を使用している場合、それらには関数があります。

REGEXP_REPLACE(col, regexp, replace)

MariaDB のドキュメントPCRE の正規表現の機能強化を参照してください。

正規表現のグループ化も使用できることに注意してください(非常に便利であることがわかりました):

SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\\2 - \\1 - \\3')

戻り値

over - stack - flow
于 2014-10-03T13:11:16.843 に答える
116

これを機能させるための私の力ずくの方法は次のとおりです。

  1. テーブルをダンプします -mysqldump -u user -p database table > dump.sql
  2. いくつかのパターンを見つけて置き換えます - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} \;、ファイルに対して実行できる他の perl 正規表現も明らかにあります。
  3. テーブルをインポートします -mysqlimport -u user -p database table < dump.sql

文字列がデータセットの他の場所にないことを確認したい場合は、いくつかの正規表現を実行して、それらがすべて同様の環境で発生することを確認してください。また、情報の深さを失うものを誤って破壊した場合に備えて、置換を実行する前にバックアップを作成することもそれほど難しくありません。

于 2012-02-26T19:52:15.047 に答える
48

最近、正規表現を使用して文字列を置き換える MySQL 関数を作成しました。私の投稿は次の場所にあります。

http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/

関数コードは次のとおりです。

DELIMITER $$

CREATE FUNCTION  `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
RETURNS VARCHAR(1000)
DETERMINISTIC
BEGIN 
 DECLARE temp VARCHAR(1000); 
 DECLARE ch VARCHAR(1); 
 DECLARE i INT;
 SET i = 1;
 SET temp = '';
 IF original REGEXP pattern THEN 
  loop_label: LOOP 
   IF i>CHAR_LENGTH(original) THEN
    LEAVE loop_label;  
   END IF;
   SET ch = SUBSTRING(original,i,1);
   IF NOT ch REGEXP pattern THEN
    SET temp = CONCAT(temp,ch);
   ELSE
    SET temp = CONCAT(temp,replacement);
   END IF;
   SET i=i+1;
  END LOOP;
 ELSE
  SET temp = original;
 END IF;
 RETURN temp;
END$$

DELIMITER ;

実行例:

mysql> select regex_replace('[^a-zA-Z0-9\-]','','2my test3_text-to. check \\ my- sql (regular) ,expressions ._,');
于 2011-06-02T15:16:20.700 に答える
46

正規表現を使用せずにこの問題を解決します。このクエリは完全一致文字列のみを置き換えます。

update employee set
employee_firstname = 
trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))

例:

emp_id 従業員の名前

ジェイ1匹

2 ジェイ・アジェイ

3 ジェイ

クエリ結果を実行した後:

emp_id 従業員の名前

1 abc

2 abc ajay

3 abc

于 2014-12-19T05:07:35.223 に答える
8

あなたはそれを行うことができます...しかしそれはあまり賢明ではありません...これは私が試みるのと同じくらい大胆です...完全な正規表現がperlなどを使用することであなたのはるかに良いことをサポートする限り。

UPDATE db.tbl
SET column = 
CASE 
WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]' 
THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
END 
WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'
于 2012-09-28T03:09:29.597 に答える
6

以下のように、SELECT クエリで IF 条件を使用できます。

「ABC」、「ABC1」、「ABC2」、「ABC3」、...を含むものを「ABC」に置き換えたいと仮定し、SELECTクエリでREGEXPとIF()条件を使用すると、これを実現できます.

構文:

SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
FROM table1 
WHERE column_name LIKE 'ABC%';

例:

SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');
于 2014-12-01T06:37:45.673 に答える