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

Ed *_*ays 116 mysql character-encoding

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

O. *_*nes 210

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

SELECT whatever
  FROM tableName 
 WHERE columnToCheck <> CONVERT(columnToCheck USING ASCII)
Run Code Online (Sandbox Code Playgroud)

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

有关更多讨论,请参阅此处 http://dev.mysql.com/doc/refman/5.7/en/charset-repertoire.html

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

  • 这是解决这个问题的绝佳解决方案,而且更加强大. (17认同)
  • 这对于查找带有重音符号(áäetc)或不属于编码的字符也很有用 (4认同)
  • 优秀的解决方案! (3认同)
  • 比使用REGEXP更好(对于我来说,寻找重音似乎不起作用),并且还提供了一种简单的机制来使所有的ascii再次出现... (2认同)

zen*_*nde 92

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

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

这是我能提出的最全面的查询.

  • -1**这可能会产生错误的结果.**例如,假设一个包含`'ā'的UTF-16列(由字节序列"0x0101"编码) - 它将被视为"ASCII"使用这个测试:*假阴性*; 实际上,某些字符集不会在"0x00"到"0x7f"内编码ASCII字符,因此此解决方案会产生误报.**不要依赖这个答案!** (14认同)
  • 到目前为止最好的答案,但它更容易这样:`SELECT*FROM table WHERE LENGTH(column)!= CHAR_LENGTH(column)` (3认同)
  • @sun:这根本没有用 - 许多字符集都是固定长度的,因此`LENGTH(列)`将是`CHAR_LENGTH(列)`的常量倍数,而与值无关. (2认同)

Cha*_*rch 60

它完全取决于您所定义的"ASCII",但我建议尝试这样的查询变体:

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9]';
Run Code Online (Sandbox Code Playgroud)

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

SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9.,-]';
Run Code Online (Sandbox Code Playgroud)

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

  • 此查询仅查找tableName中不包含字母数字字符的所有行.这不回答这个问题. (9认同)
  • 这适用于根本没有任何ascii字符的列,因此它将错过那些混合了ascii和非ascii字符的列.zende的以下答案检查一个或多个非ascii字符.这在很大程度上帮助了我`SELECT*FROM tbl WHERE colname NOT REGEXP'^ [A-Za-z0-9 \.,@&\(\)\ - ]*$';` (6认同)
  • 你不应该逃避连字符和句号吗?(因为它们在正则表达式中确实有特殊含义.)SELECT*FROM tableName WHERE NOT columnToCheck REGEXP'[A-Za-z0-9 \.,\ - ]'; (3认同)
  • @Tooony不,在一个集合中,一个时期只是意味着自己,而破折号在其他角色之间只有特殊意义.在集合的最后,它只意味着它自己. (3认同)
  • 这仅适用于(无论如何对我而言)查找不包含这些字符的字符串。它找不到包含 ASCII 和非 ASCII 字符混合的字符串。 (2认同)

小智 42

这可能是你正在寻找的:

select * from TABLE where COLUMN regexp '[^ -~]';
Run Code Online (Sandbox Code Playgroud)

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

  • 对我来说很棒."regexp'[^ - 〜]'"表示字符在空格""之前或"〜"或ASCII 32 - 126之后.所有字母,数字和符号,但没有不可打印的东西. (7认同)
  • 请注意 [文档](https://dev.mysql.com/doc/en/regexp.html) 中的**警告**:“*`REGEXP` 和 `RLIKE` 运算符以字节方式工作,所以它们不是多字节安全的,并且可能会产生多字节字符集的意外结果。此外,这些运算符按字节值比较字符,即使给定的排序规则将它们视为相等,重音字符也可能不相等。* ” (2认同)

Rob*_*ley 14

上面每个人的例子中缺少一个字符是终止字符(\ 0).这对于MySQL控制台输出是不可见的,并且不能被迄今提到的任何查询发现.查找它的查询很简单:

select * from TABLE where COLUMN like '%\0%';
Run Code Online (Sandbox Code Playgroud)