如何从MySQL中的字符串中删除所有非字母数字字符?

Dyl*_*lan 56 regex mysql string alphanumeric

我正在研究比较字符串的例程,但为了提高效率,我需要删除所有不是字母或数字的字符.

我现在正在使用多种REPLACE功能,但也许有更快更好的解决方案?

Rya*_*ton 87

这些答案都不适合我.我必须创建一个名为alphanum的函数,它为我剥离了字符:

DROP FUNCTION IF EXISTS alphanum; 
DELIMITER | 
CREATE FUNCTION alphanum( str CHAR(255) ) RETURNS CHAR(255) DETERMINISTIC
BEGIN 
  DECLARE i, len SMALLINT DEFAULT 1; 
  DECLARE ret CHAR(255) DEFAULT ''; 
  DECLARE c CHAR(1); 
  SET len = CHAR_LENGTH( str ); 
  REPEAT 
    BEGIN 
      SET c = MID( str, i, 1 ); 
      IF c REGEXP '[[:alnum:]]' THEN 
        SET ret=CONCAT(ret,c); 
      END IF; 
      SET i = i + 1; 
    END; 
  UNTIL i > len END REPEAT; 
  RETURN ret; 
END | 
DELIMITER ; 
Run Code Online (Sandbox Code Playgroud)

现在我能做到:

select 'This works finally!', alphanum('This works finally!');
Run Code Online (Sandbox Code Playgroud)

我得到:

+---------------------+---------------------------------+
| This works finally! | alphanum('This works finally!') |
+---------------------+---------------------------------+
| This works finally! | Thisworksfinally                |
+---------------------+---------------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

欢呼!

  • 您的正则表达式不包含重音字符。对于大多数语言来说,使用 ```[^-'0-9a-zÀ-ÿ]]* ``` 应​​该可以解决问题。更多信息在这里:/sf/ask/1727368401/ (3认同)
  • 我认为这种自我回答应该得到更多的支持。做得好男人。 (2认同)
  • 这是迄今为止最好的答案.此外,它易于扩展.我习惯用`[:digit:]`代替`[:alnum:]`.谢谢! (2认同)
  • 对于想知道为什么这在 Mariadb 中不起作用的人:我删除了 DELIMITER 行,将最后一行更改为 'END //' 并将正则表达式更改为:'Mar[[:alnum:]]' 以使其工作。 (2认同)

Kev*_*ton 20

从性能的角度来看,(并且假设你读的比你写的多)

我认为最好的方法是预先计算并存储列的剥离版本,这样就可以减少变换.

然后,您可以在新列上放置索引并让数据库为您完成工作.


Joh*_*ica 13

SELECT teststring REGEXP '[[:alnum:]]+';

SELECT * FROM testtable WHERE test REGEXP '[[:alnum:]]+'; 
Run Code Online (Sandbox Code Playgroud)

请参阅:http://dev.mysql.com/doc/refman/5.1/en/regexp.html
向下滚动到以下部分: [:character_class:]

如果你想操作字符串最快的方法是使用str_udf,请参阅:https:
//github.com/hholzgra/mysql-udf-regexp

  • MySQL正则表达式只能查找数据.他们不能做替换,所以这根本不会对OP有所帮助. (11认同)

mic*_*czy 12

从 MySQL 8.0 开始,您可以使用正则表达式从字符串中删除非字母数字字符。有方法REGEXP_REPLACE

这是删除非字母数字字符的代码:

UPDATE {table} SET {column} = REGEXP_REPLACE({column}, '[^0-9a-zA-Z ]', '')
Run Code Online (Sandbox Code Playgroud)

  • 对于 MySQL < 8.0,您可以使用其他答案推荐的内容。但2018年4月就发布了8.0,所以是时候升级了。 (3认同)

小智 6

根据Ryan Shillington的回答,修改为使用超过255个字符的字符串并保留原​​始字符串的空格.

仅供参考lower(str).

我用它来比较字符串:

DROP FUNCTION IF EXISTS spacealphanum;
DELIMITER $$
CREATE FUNCTION `spacealphanum`( str TEXT ) RETURNS TEXT CHARSET utf8
BEGIN 
  DECLARE i, len SMALLINT DEFAULT 1; 
  DECLARE ret TEXT DEFAULT ''; 
  DECLARE c CHAR(1); 
  SET len = CHAR_LENGTH( str ); 
  REPEAT 
    BEGIN 
      SET c = MID( str, i, 1 ); 
      IF c REGEXP '[[:alnum:]]' THEN 
        SET ret=CONCAT(ret,c); 
      ELSEIF  c = ' ' THEN
          SET ret=CONCAT(ret," ");
      END IF; 
      SET i = i + 1; 
    END; 
  UNTIL i > len END REPEAT; 
  SET ret = lower(ret);
  RETURN ret; 
  END $$
  DELIMITER ;
Run Code Online (Sandbox Code Playgroud)


use*_*ond 6

经过验证的拉丁和西里尔字母字符的直接解决方案:

DELIMITER //

CREATE FUNCTION `remove_non_numeric_and_letters`(input TEXT)
  RETURNS TEXT
  BEGIN
    DECLARE output TEXT DEFAULT '';
    DECLARE iterator INT DEFAULT 1;
    WHILE iterator < (LENGTH(input) + 1) DO
      IF SUBSTRING(input, iterator, 1) IN
         ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?')
      THEN
        SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
      END IF;
      SET iterator = iterator + 1;
    END WHILE;
    RETURN output;
  END //

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

用法:

-- outputs "hello12356"
SELECT remove_non_numeric_and_letters('hello - 12356-?????? ""]')
Run Code Online (Sandbox Code Playgroud)


vdd*_*vdd 5

我能够找到(和使用)的最快方法是使用convert().

来自Doc.带USING的CONVERT()用于在不同字符集之间转换数据.

例:

convert(string USING ascii)
Run Code Online (Sandbox Code Playgroud)

在您的情况下,正确的字符集将是自定义的

来自Doc的说明.在使用的形式CONVERT()可为4.1.0.