MySQL'de ASCII olmayan karakterleri nasıl bulabilirim?


124

Excel'den içe aktarılan bazı verilerin bulunduğu bir MySQL veritabanıyla çalışıyorum . Veriler, ASCII olmayan karakterler (uzun çizgiler, vb.) İle gizli satır başları veya satır beslemeleri içerir. MySQL kullanarak bu kayıtları bulmanın bir yolu var mı?


8
Ollie Jones'un çok daha iyi bir cevabı var (altını kontrol edin).
Jonathan Arkell

1
@JonathanArkell Artık dipte değil :)
Brilliand

Düzeltme .. ortayı kontrol edin! ;)
Jonathan Arkell

Cevap bu
@Jonathan

Yanıtlar:


64

Bu tam olarak neyi "ASCII" olarak tanımladığınıza bağlıdır, ancak bunun gibi bir sorgunun varyantını denemenizi öneririm:

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

Bu sorgu, columnToCheck'in alfanümerik olmayan karakterleri içerdiği tüm satırları döndürür. Kabul edilebilir başka karakterleriniz varsa, bunları normal ifadedeki karakter sınıfına ekleyin. Örneğin, nokta, virgül ve kısa çizgi uygunsa, sorguyu şu şekilde değiştirin:

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

MySQL belgelerinin en alakalı sayfası muhtemelen 12.5.2 Normal İfadeler'dir .


3
Kısa çizgi ve noktadan kaçmanız gerekmez mi? (Normal ifadede özel anlamları olduğundan.) SELECT * FROM tableName NEREDE columnToCheck REGEXP '[A-Za-z0-9 \., \ -]';
Tooony

3
@Tooony Hayır, bir kümenin içinde, nokta sadece kendisi anlamına gelir ve kısa çizgi yalnızca diğer karakterler arasında özel bir anlama sahiptir. Setin sonunda sadece kendisi demektir.
Michael Speer

10
Bu sorgu yalnızca tableName'de alfanümerik karakter içermeyen tüm satırları bulur. Bu soruya cevap vermiyor.
Rob Bailey

8
Bu, hiç ascii karakteri olmayan sütunlar içindir, bu nedenle ascii ve ascii olmayan karakterlerin karışımına sahip olanları özleyecektir. Aşağıdaki zende cevabı, bir veya daha fazla ascii olmayan karakteri kontrol eder. Bu bana çoğunlukla yardımcı olduSELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
Frank Forte

1
Bu sadece (yine de benim için) bu karakterlerden HİÇBİRİ içermeyen dizeleri bulmak için çalışır. ASCII ve ASCII olmayan karakterlerin karışımını içeren dizeleri bulamaz.
Ian

236

MySQL, bu tür sorunlara yardımcı olabilecek kapsamlı karakter seti yönetimi sağlar.

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

CONVERT(col USING charset)Fonksiyon değiştirme karakterleri içine unconvertable karakterleri döner. Ardından, dönüştürülen ve dönüştürülmeyen metin eşit olmayacaktır.

Daha fazla tartışma için buna bakın. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html

ASCII yerine istediğiniz herhangi bir karakter seti adını kullanabilirsiniz. Örneğin, 1257 kod sayfasında (Litvanyaca, Letonca, Estonca) hangi karakterlerin doğru şekilde işlenmediğini öğrenmek istiyorsanız şunu kullanın:CONVERT(columnToCheck USING cp1257)


20
Bu, bu soruna mükemmel bir çözüm ve çok daha sağlam.
CraigDouglas

5
bu, aksanlı karakterleri (á ä vb.) veya kodlamaya ait olmayan karakterleri bulmak için de kullanışlıdır
Glasnhost

3
REGEXP kullanmaktan çok daha iyi (bu benim için aksan bulmakta işe yaramıyor gibi görünüyor) ve aynı zamanda her şeyi tekrar ascii yapmak için basit bir mekanizma sağlıyor ...
Dirk Conrad Coetsee

1
Bu cevap olağanüstü çalışır ve herhangi bir ASCII olmayan karakterler yerine içerirler sadece dizeleri içeren dizeleri getirecektir sadece ASCII olmayan karakterler. Teşekkür ederim!
Ian

2
Olağanüstü çözüm!
Mad Dog Tannen

93

ASCII'yi ondalık değeri 0 - 127 (0x00 - 0x7F) olan tüm karakterler olarak tanımlayabilir ve aşağıdaki sorguyu kullanarak ASCII olmayan karakterler içeren sütunları bulabilirsiniz.

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

Bu bulabildiğim en kapsamlı sorguydu.


3
En iyi cevap şu ana kadar, ama böyle daha da kolay:SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
SuN

15
-1 Bu hatalı sonuçlara yol açabilir. Örneğin, 'ā'(bayt dizisi tarafından kodlanan) içeren bir UTF-16 sütununa sahip olduğunu varsayalım 0x0101- bu test kullanıldığında "ASCII" olarak kabul edilecektir: yanlış negatif ; aslında, bazı karakter kümeleri içindeki ASCII karakterlerini kodlamaz 0x00, 0x7fbunun üzerine bu çözüm yanlış bir pozitif verir. BU CEVABA GÜVENMEYİN!
eggyal

2
@sun: Bu hiç yardımcı olmuyor - birçok karakter kümesi sabit uzunluktadır ve bu nedenle değerden bağımsız olarak LENGTH(column)sabit bir katı olacaktır CHAR_LENGTH(column).
eggyal

49

Muhtemelen aradığınız şey bu:

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

SÜTUN'un ASCII olmayan karakterler (veya yeni satır gibi yazdırılamayan ASCII karakterleri) içerdiği tüm satırları döndürmelidir.


7
Benim için harika çalışıyor. "regexp '[^ - ~]'", boşluktan önce "" veya sonra "~" veya ASCII 32 - 126 olan bir karaktere sahip olduğu anlamına gelir. Tüm harfler, sayılar ve semboller, ancak yazdırılamayan şeyler yoktur.
Josh

Hatta tişört olarak da alabilirsiniz;) catonmat.net/blog/my-favorite-regex
SamGoody

1
Not uyarıyı içinde belgeler : " ve . Operatörleri multi-byte güvenli değildir ve çoklu bayt karakter setleri ile beklenmeyen sonuçlar doğurabilir, böylece bayt bazlı şekilde çalışmak ise ek, bu operatörler kendi bayt değerleriyle karakterleri karşılaştırmak ve aksanlı karakterler, belirli bir harmanlama onlaraREGEXPRLIKE
eşitmiş

1
Bunun için teşekkürler. Merak ettiğim şey, yeni bir karakterin nasıl değiştirileceğidir - ör. â
mars-o

1
@ mars-o - siyah elmas geçersiz bir utf8 karakterini gösterir. Daha fazla tartışma burada
Rick James

14

Yukarıdaki herkesin örneklerinde eksik olan bir karakter, sonlandırma karakteridir (\ 0). Bu, MySQL konsol çıktısı için görünmezdir ve daha önce bahsedilen sorguların hiçbiri tarafından keşfedilemez. Bulma sorgusu basitçe:

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

4

Doğru cevaba dayanarak, ancak ASCII kontrol karakterlerini de hesaba katarak benim için işe yarayan çözüm şudur:

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

Aynı şeyi yapar: bir sütunda ASCII aralığı ihlallerini arar, ancak kod noktaları için onaltılı gösterim kullandığından kontrol karakterlerini de aramanıza izin verir. Karşılaştırma veya dönüştürme olmadığından (@ Ollie'nin cevabının aksine), bu da önemli ölçüde daha hızlı olmalıdır. (Özellikle MySQL regex sorgusunda erken sonlandırma yapıyorsa, ki kesinlikle yapması gerekir.)

Ayrıca sıfır uzunluklu alanların döndürülmesini de önler. Daha iyi performans gösterebilecek biraz daha uzun bir sürüm istiyorsanız, bunun yerine şunu kullanabilirsiniz:

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

Sıfır uzunluklu sonuçlardan kaçınmak için, bunları normal ifade geçişi için dikkate almadan ayrı bir uzunluk kontrolü yapar. Sahip olduğunuz sıfır uzunluklu girişlerin sayısına bağlı olarak, bu önemli ölçüde daha hızlı olabilir.

0x00-0xFF değerlerinin ASCII ile aynı değerlerle eşleşmediği varsayılan karakter kümeniz tuhaf bir şeyse (herhangi bir yerde böyle bir karakter kümesi var mı?), Bu yanlış bir pozitif döndürecektir. Aksi takdirde, keyfini çıkarın!


1
00-FF, kontrol eden tüm olası 8 bitlik değerleri içerir REGEXP. Bu nedenle her zaman eşleşmesi garantilidir. Ayrıca ^$muhtemelen istediğin şey değil.
Rick James

8 bitlik karakterlerin tümünü bulmak için kesinlikle en iyi REGEXP çözümü, ancak CONVERT (col USING charset) çözümü kadar iyi değildir; bu, görüntü karakterlerini belirli bir karakter setiyle sınırlarken kontrol karakterlerine de izin verir.
Ian

1

Özel karakter kayıtlarını aramak için bu sorguyu kullanmayı deneyin

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

0

@ zende'nin yanıtı, sütunları ascii ve ascii olmayan karakterlerin karışımıyla kaplayan tek cevaptı, ama aynı zamanda sorunlu hex şeyine de sahipti. Bunu kullandım:

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


-2

bu soru için şu yöntemi de kullanabiliriz:

Sql hayvanat bahçesinden soru:
PETER GRÜNBERG tarafından kazanılan ödülün tüm ayrıntılarını bulun

ASCII olmayan karakterler

ans: nobel'den * seçin; kazanan 'P% GR% _% berg' gibi;


1
Sorunun bağlantısı nerede?
Nico Haase
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.