MySQLで非ASCII文字を検索するにはどうすればよいですか?


124

Excelからインポートされたデータが含まれているMySQLデータベースを使用しています。データには、非ASCII文字(ダッシュなど)と、非表示の改行または改行が含まれます。MySQLを使用してこれらのレコードを見つける方法はありますか?


8
Ollie Jonesの回答ははるかに優れています(下部を確認してください)。
ジョナサンアーケル

1
@JonathanArkellもう底にはありません:)
ブリリアント

訂正..途中チェック!;)
ジョナサンアーケル2014年

これは、@ Jonathanがstackoverflow.com/a/11741314/792066
Braiam

回答:


64

「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ドキュメントの最も関連性の高いページは、おそらく12.5.2正規表現です。


3
ハイフンとピリオドをエスケープしてはいけませんか?(正規表現では特別な意味があるため。)SELECT * FROM tableName WHERE NOT columnToCheck REGEXP '[A-Za-z0-9 \。、\-]';
Tooony 2009年

3
@Tooonyいいえ、セット内では、ピリオドはそれ自体を意味し、ダッシュは他の文字の間で特別な意味しかありません。セットの最後では、それはそれ自体を意味します。
Michael Speer

10
このクエリは、英数字を含まないtableName内のすべての行のみを検索します。これは質問の答えにはなりません。
Rob Bailey

8
これは、ASCII文字がまったく含まれていない列のため、ASCII文字とASCII以外の文字が混在している列は表示されません。以下のzendeからの回答は、1つ以上の非ASCII文字をチェックします。これは、ほとんどの部分は私を助けたSELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
フランク・フォルテ

1
これは(とにかく私にとって)これらの文字をNONE含む文字列を見つけるためにのみ機能します。ASCII文字と非ASCII文字が混在する文字列は検出されません。
Ian

236

MySQLは、この種の問題に役立つ包括的な文字セット管理を提供します。

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

このCONVERT(col USING charset)関数は、変換できない文字を置換文字に変換します。次に、変換されたテキストと変換されていないテキストは等しくありません。

詳細については、こちらをご覧ください。https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html

ASCIIの代わりに、任意の文字セット名を使用できます。たとえば、コードページ1257(リトアニア語、ラトビア語、エストニア語)で正しく表示されない文字を見つけたい場合は、次を使用します。CONVERT(columnToCheck USING cp1257)


20
これはこの問題の優れた解決策であり、はるかに堅牢です。
CraigDouglas

5
これは、アクセントのある文字(
áä

3
REGEXP(アクセントを見つけるために私には機能しないように見える)を使用するよりもはるかに優れており、すべてを再びASCIIにするための簡単なメカニズムも提供します...
Dirk Conrad Coetsee

1
この答えは素晴らしく機能し、非ASCII文字のみを含む文字列だけでなく、非ASCII文字を含む文字列を表示します。ありがとうございました!
Ian

2
優れたソリューション!
Mad Dog Tannen

93

次のクエリを使用して、ASCIIを10進数の値が0-127(0x00-0x7F)のすべての文字として定義し、非ASCII文字の列を検索できます。

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

これは私が思いつくことができる最も包括的なクエリでした。


3
ベストこれまでの答えが、それはこのようにも簡単です:SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
太陽の

15
-1 これは誤った結果をもたらす可能性があります。 一つは含むUTF-16カラムがあること、例えば、仮定'ā'(バイト配列によってコードを0x0101) -それはみなされるであろう「ASCII」は、この試験を使用して:偽陰性を、実際、一部の文字セットはASCII文字をにエンコードしない0x00ため0x7f、このソリューションでは誤検知が発生します。 この答えに依存しないでください!
eggyal 2014

2
@sun:それはまったく役に立ちません-多くの文字セットは固定長であるため、値LENGTH(column)CHAR_LENGTH(column)関係なく定数の倍数になります。
eggyal 2014

49

これはおそらくあなたが探しているものです:

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

COLUMNに非ASCII文字(または改行などの印刷できないASCII文字)が含まれているすべての行を返します。


7
私にとってはうまくいきます。"regexp '[^-〜]'"は、スペース ""の前または "〜"またはASCII 32-126の後にある文字を意味します。すべての文字、数字、および記号ですが、印刷できないものはありません。
Josh、

Tシャツとしても入手できます;) catonmat.net/blog/my-favorite-regex
SamGoody

1
注意警告ドキュメント」:そして彼らは、マルチバイトの安全ではなく、マルチバイト文字セットで予期しない結果が生じることがありので、また、これらの事業者は、そのバイト値で文字を比較し、バイト単位方式で事業者の仕事をして。アクセント付き文字は、特定の照合でそれらが等しいものとして扱われても、等しいものとして比較されない場合があります。 "REGEXPRLIKE
eggyal

1
これをありがとう。私が不思議に思っているのは、置換文字を置き換える方法です-例–â
mars-o

1
@ mars-o-黒いひし形は無効なutf8文字を示します。ここでの
リック・ジェームズ

14

上記のすべての例で欠けている文字の1つは、終了文字(\ 0)です。これはMySQLコンソールの出力からは見えず、これまでに述べたどのクエリからも発見できません。それを見つけるためのクエリは単純です:

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

4

正しい答えに基づいていますが、ASCII制御文字も考慮に入れて、私にとってうまくいった解決策は次のとおりです。

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

同じことを行います。列のASCII範囲の違反を検索しますが、コードポイントに16進表記を使用するため、制御文字も検索できます。@Ollieの回答とは異なり、比較や変換は行われないため、これも大幅に高速になります。(特にMySQLが正規表現クエリで早期終了を行う場合、それは間違いなくそうすべきです。)

また、長さがゼロのフィールドを返さないようにします。パフォーマンスが向上する少し長いバージョンが必要な場合は、代わりにこれを使用できます。

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

正規表現のパスを考慮せずに、長さゼロの結果を回避するために、長さを個別にチェックします。長さゼロのエントリの数によっては、これが大幅に速くなる場合があります。

デフォルトの文字セットが奇妙なもので、0x00-0xFFがASCIIと同じ値にマッピングされていない場合(そのような文字セットはどこかに存在しますか?)、これは誤検知を返します。それ以外の場合は、お楽しみください!


1
00-FFにはすべての可能な8ビット値が含まれており、これREGEXPがチェック対象です。したがって、常に一致することが保証されています。また^$、おそらくあなたが望んでいたものではありません。
リックジェームズ

間違いなく、すべての8ビット文字を見つけるのに最適なREGEXPソリューションですが、表示文字を特定の文字セットに制限しながら制御文字を許可するCONVERT(col USING charset)ソリューションほど優れていません。
Ian

1

このクエリを使用して特殊文字レコードを検索してみてください

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

0

@zendeの回答は、ASCII文字と非ASCII文字が混在する列をカバーした唯一の回答でしたが、問題のある16進数の問題もありました。私はこれを使いました:

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


-2

この質問では、次の方法も使用できます。

SQL
Zoo からの質問:PETERGRÜNBERGが獲得した賞の詳細をすべて見つけてください

非ASCII文字

ans:select * fromノーベルの「P%GR%_%berg」のような勝者。


1
質問との関係はどこにありますか?
ニコハーゼ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.