如何在 MySQL 中找到非 ASCII 字符?

我正在使用一个 MySQL 数据库,它有一些从 Excel导入的数据。数据包含非 ASCII字符(em 破折号等)以及隐藏的回车符或换行符。有没有办法使用 MySQL 查找这些记录?

135231 次浏览

这完全取决于你定义的“ ASCII”是什么,但我建议尝试一个类似这样的查询变体:

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9]';

该查询将返回 ColumnToCheck 包含任何非字母数字字符的所有行。如果您有其他可接受的字符,请将它们添加到正则表达式中的字符类中。例如,如果句点、逗号和连字符都可以,则将查询更改为:

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9.,-]';

MySQL 文档中最相关的页面可能是 正则表达式

这可能就是你要找的:

select * from TABLE where COLUMN regexp '[^ -~]';

它应该返回 COLUMN 包含非 ASCII 字符(或非打印 ASCII 字符,如换行符)的所有行。

可以将 ASCII 定义为十进制值为0-127(0x00-0x7F)的所有字符,并使用以下查询查找具有非 ASCII 字符的列

SELECT * FROM TABLE WHERE NOT HEX(COLUMN) REGEXP '^([0-7][0-9A-F])*$';

这是我能想到的最全面的查询。

MySQL 提供了全面的字符集管理,可以帮助解决这类问题。

SELECT whatever
FROM tableName
WHERE columnToCheck <> CONVERT(columnToCheck USING ASCII)

CONVERT(col USING charset)函数将不可转换的字符转换为替换字符。然后,转换的文本和未转换的文本将是不等的。

更多讨论请参见此文

您可以使用任何字符集名称来代替 ASCII。例如,如果您想找出代码页1257(立陶宛语、拉脱维亚语、爱沙尼亚语)中哪些字符不能正确呈现,请使用 CONVERT(columnToCheck USING cp1257)

上面的示例中缺少的一个字符是终止字符(0)。这对于 MySQL 控制台输出是不可见的,也不会被前面提到的任何查询发现。查找它的查询很简单:

select * from TABLE where COLUMN like '%\0%';

基于正确的答案,但同时考虑到 ASCII 控制字符,对我有效的解决方案是这样的:

SELECT * FROM `table` WHERE NOT `field` REGEXP  "[\\x00-\\xFF]|^$";

它做同样的事情: 在列中搜索违反 ASCII 范围的内容,但是也允许搜索控制字符,因为它使用十六进制表示法表示代码点。由于没有比较或转换(不像@Ollie 的回答) ,这也应该更快。(特别是如果 MySQL 对正则表达式查询进行提前终止,它肯定应该这样做。)

它还避免返回长度为零的字段。如果你想要一个稍微长一点的版本,可能性能更好,你可以使用以下代码:

SELECT * FROM `table` WHERE `field` <> "" AND NOT `field` REGEXP  "[\\x00-\\xFF]";

它对长度进行单独的检查,以避免出现零长度的结果,而不考虑正则表达式传递的结果。根据您拥有的零长度条目的数量,这可能会快得多。

请注意,如果您的默认字符集是一些奇怪的地方0x00-0xFF 不映射到相同的值作为 ASCII (有这样的字符集存在吗?)这将返回一个假阳性。否则,尽情享受吧!

尝试使用此查询搜索特殊字符记录

SELECT *
FROM tableName
WHERE fieldName REGEXP '[^a-zA-Z0-9@:. \'\-`,\&]'

@ zende 的答案是唯一一个混合了 ascii 和 non ascii 字符的专栏,但它也有那个问题的十六进制的东西。我用了这个:

SELECT * FROM `table` WHERE NOT `column` REGEXP '^[ -~]+$' AND `column` !=''

对于这个问题我们也可以用这个方法:

来自 sql 动物园的问题:
找到所有细节的奖项获得彼得格兰伯格

非 ASCII 字符

安斯: 从诺贝尔奖中选择 * ,获奖者如“ P% GR% _% berg”;

在 Oracle 中,我们可以使用以下代码。

SELECT * FROM TABLE_A WHERE ASCIISTR(COLUMN_A) <> COLUMN_A;