MySQL에서 ASCII가 아닌 문자를 어떻게 찾을 수 있습니까?


124

Excel 에서 가져온 일부 데이터가있는 MySQL 데이터베이스를 사용하고 있습니다 . 데이터에는 비 ASCII 문자 (엠 대시 등)와 숨겨진 캐리지 리턴 또는 줄 바꿈이 포함됩니다. MySQL을 사용하여 이러한 레코드를 찾는 방법이 있습니까?


8
Ollie Jones가 훨씬 더 나은 답변을 제공합니다 (아래 참조).
Jonathan Arkell

1
@JonathanArkell 더 이상 바닥에 없습니다 :)
Brilliand

수정 .. 중간을 확인하세요! ;)
Jonathan Arkell 2014 년

이 @ 조나단 대해 대답 말하고있다 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

3
@Tooony 아니요, 집합 내에서 마침표는 자신을 의미하고 대시는 다른 문자간에 특별한 의미 만 있습니다. 세트의 끝에는 그 자체만을 의미합니다.
Michael Speer 2012 년

10
이 쿼리는 영숫자를 포함하지 않는 tableName의 모든 행만 찾습니다. 이것은 질문에 대한 답이 아닙니다.
Rob Bailey

8
이는 ASCII 문자가 전혀없는 열을위한 것이므로 ASCII 문자와 비 ASCII 문자가 혼합 된 열은 누락됩니다. zende의 아래 답변은 하나 이상의 비 ASCII 문자를 확인합니다. 이것은 대부분 나를 도와SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
프랭크 포르테에게

1
이것은 (어쨌든 나를 위해) 해당 문자를 포함하지 않는 문자열을 찾는 데에만 작동합니다. 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
이것은 악센트 (á ä 등)가있는 문자 나 인코딩에 속하지 않는 문자를 찾는 데에도 유용합니다.
Glasnhost

3
훨씬 더 (악센트를 찾기 위해 나를 위해 작동하지 않는 것) 정규 표현식을 사용하는 것보다도 ... 다시 모든 아스키를 만들기위한 간단한 메커니즘을 제공
더크 콘래드 Coetsee

1
이 답변은 훌륭하게 작동 및 비 ASCII 문자가 아닌 포함 된 단지 문자열이 포함 된 문자열 나타납니다 ASCII 문자가 아닌 문자. 감사합니다!
Ian

2
탁월한 솔루션!
Mad Dog Tannen 2018

93

10 진수 값이 0-127 (0x00-0x7F) 인 모든 문자로 ASCII를 정의하고 다음 쿼리를 사용하여 비 ASCII 문자가있는 열을 찾을 수 있습니다.

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

이것은 제가 생각 해낼 수있는 가장 포괄적 인 질문이었습니다.


3
지금까지 최고의 답변이지만 다음과 같이 더 쉽습니다.SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
SuN

15
-1 이것은 잘못된 결과를 초래할 수 있습니다. 예를 들어, 'ā'(바이트 시퀀스로 인코딩 된) UTF-16 열이 있다고 가정합니다. 0x0101이 테스트를 사용하면 "ASCII"로 간주됩니다 . 거짓 음성 ; 실제로, 일부 문자 집합 내에 있지 인코딩 ASCII 문자를 수행 0x00하는 0x7f이 솔루션은 오 탐지를 얻을하곤했다. 이 답변에 의존하지 마십시오!
eggyal

2
@sun : 전혀 도움이되지 않습니다. 많은 문자 집합이 고정 길이이므로 값 LENGTH(column)CHAR_LENGTH(column)관계없이 상수 배수가 됩니다.
eggyal

49

이것은 아마도 당신이 찾고있는 것입니다.

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

COLUMN에 ASCII가 아닌 문자 (또는 줄 바꿈과 같은 인쇄 할 수없는 ASCII 문자)가 포함 된 모든 행을 반환해야합니다.


7
나를 위해 잘 작동합니다. "regexp '[^-~]'"는 공백 ""앞, "~"또는 ASCII 32-126 뒤에있는 문자가 있음을 의미합니다. 모든 문자, 숫자 및 기호는 인쇄 할 수 없습니다.
Josh

티셔츠 로도
SamGoody

1
노트 경고 에서 문서를 " 하고 . 사업자들이 멀티 바이트 안전하지 않습니다 및 멀티 바이트 문자 집합에 예기치 않은 결과가 발생할 수 있으므로, 바이트 현명한 방식으로 작동에서 추가, 이러한 연산자가 바이트 값으로 문자를 비교하고 악센트 부호가있는 문자는 지정된 데이터 정렬에서 동일하게 취급하더라도 동일하게 비교되지 않을 수 있습니다. "REGEXPRLIKE
eggyal

1
감사합니다. 내가 궁금한 것은 대체 문자를 바꾸는 방법입니다. 예 : â
mars-o

1
@ mars-o-검은 색 다이아몬드는 잘못된 utf8 문자를 나타냅니다. 더 많은 토론 여기
릭 제임스

14

위의 모든 예에서 누락 된 문자 중 하나는 종료 문자 (\ 0)입니다. 이것은 MySQL 콘솔 출력에 표시되지 않으며 지금까지 언급 한 쿼리로 검색 할 수 없습니다. 이를 찾는 쿼리는 다음과 같습니다.

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

4

정답을 기반으로하지만 ASCII 제어 문자도 고려하면 저에게 도움이 된 솔루션은 다음과 같습니다.

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

동일한 작업을 수행합니다. 열에서 ASCII 범위 위반을 검색하지만 코드 포인트에 대해 16 진수 표기법을 사용하기 때문에 제어 문자도 검색 할 수 있습니다. @Ollie의 답변과 달리 비교 또는 변환이 없기 때문에 이것은 훨씬 더 빠릅니다. (특히 MySQL이 정규식 쿼리에서 조기 종료를 수행하는 경우 확실히해야합니다.)

또한 길이가 0 인 필드를 반환하지 않습니다. 더 나은 성능을 발휘할 수있는 약간 더 긴 버전을 원하면 다음을 대신 사용할 수 있습니다.

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

정규식 패스를 고려하지 않고 길이가 0 인 결과를 피하기 위해 길이에 대한 별도의 검사를 수행합니다. 길이가 0 인 항목의 수에 따라 이것은 훨씬 더 빠를 수 있습니다.

기본 문자 집합이 0x00-0xFF가 ASCII와 동일한 값에 매핑되지 않는 기괴한 경우 (이러한 문자 집합이 어디에나 존재합니까?) 거짓 긍정을 반환합니다. 그렇지 않으면 즐기십시오!


1
00-FF에는 가능한 모든 8 비트 값이 포함됩니다 REGEXP. 따라서 항상 일치하는 것이 보장됩니다. 또한 ^$당신이 원하는 것이 아닐 수도 있습니다.
Rick James

모든 8 비트 문자를 찾기위한 최고의 REGEXP 솔루션이지만 표시 문자를 특정 문자 세트로 제한하면서 제어 문자를 허용하는 CONVERT (col USING charset) 솔루션만큼 좋지는 않습니다.
Ian

1

이 쿼리를 사용하여 특수 문자 레코드를 검색해보십시오.

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

0

@zende의 대답은 ascii 및 non ascii 문자가 혼합 된 열을 덮은 유일한 대답이지만 문제가있는 16 진수도 있습니다. 나는 이것을 사용했다 :

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


-2

이 질문에 대해 다음 방법을 사용할 수도 있습니다.

SQL 동물원의 질문 :
PETER GRÜNBERG가 수상한 상품에 대한 모든 세부 정보 찾기

비 ASCII 문자

ans : 승자는 'P % GR % _ % berg'와 같은 노벨에서 선택 *;


1
질문에 대한 연결은 어디입니까?
Nico Haase 2018 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.