拿到一份数据,做数据清洗时遇到了奇怪的问题,RT,不清楚是 MySQL 是正则匹配比较特殊还是我使用的姿势不对。
MySQL 版本 5.7, 编码 utf8mb4
正则匹配中文我一般用下面两种表达式,后者为前者对应的 unicode,用正则测试工具没什么问题。
[一-龥]
[\u4e00-\u9fa5]
但在 MySQL 中这两种正则写法查询结果却完全不一样,也搜到了一些不同的写法,基本都无法准确查询出含中文的数据,多少会有一些含有特殊字符的数据,比如 俄文:
ООО АВС-Электро
ООО ИНТЕР
不过,用正则工具测试,又匹配不上这些特殊字符。
正则在线测试:https://www.sojson.com/regex/
几种 SQL 写法参考
测试的几种 SQL 写法:
- 这种写法查询匹配到的数据目前是最准确的,不过还是含有俄文 或其它特殊字符。
SELECT name FROM user WHERE NOT (name REGEXP "[\u4e00-\u9fa5]");
奇怪的地方在于,对照上面中文正则范围,这个 SQL 语义应该是:查询 name 中不含中文的数据。结果这个 SQL 查询到的中文数据可能是最准确的。
参考前面 SQL 换种写法,在正则中取反,查询到的结果却完全不对,连普通的英文字符也都查询出来了。
SELECT name FROM user WHERE name REGEXP "[^\u4e00-\u9fa5]";
所以,真正的语义可能并不是我以为的那样。
- 这种写法才符合一般的正则匹配思路。
SELECT name FROM user WHERE name REGEXP "[一-龥]";
但查询到的数量是第1种方法的 9 倍,多出来了很多含特殊字符的数据,比如带变音符号的字母
CÔNG TY TNHH XE ĐẠP ĐIỆN ĐÀO KHÔI
这些字符同样,用正则工具测试也是匹配不上的。
- 这种查询通过判断字符长度来查询,与第2种方法中查询的数量一样
SELECT name FROM user WHERE length(name)!=char_length(name);
AI 可能也被问糊涂了,已经是建议在应用层面判断字符串中是否包含中文。当然,应用中正则应该会准确多了,实在没办法的话,就只好 MySQL 查询后,在代码中再加一层判断。
那么,还有其它方法可以用来在 MySQL 查询中文么,没想到会出现现在这种情况。
然后,目前第1种 SQL 可能是匹配准确率最高的,不过,不太理解,有没有热心大佬可以帮忙解释一下。