2008-12-30 12 views
90

मैं एक MySQL डेटाबेस के साथ काम कर रहा हूं जिसमें Excel से कुछ डेटा आयात किया गया है। डेटा में गैर-ASCII वर्ण (एम डैश इत्यादि) के साथ-साथ छिपे हुए कैरिज रिटर्न या लाइन फ़ीड्स शामिल हैं। क्या MySQL का उपयोग करके इन रिकॉर्ड्स को खोजने का कोई तरीका है?मैं MySQL में गैर-ASCII वर्ण कैसे प्राप्त कर सकता हूं?

+7

ओली जोन्स का एक बेहतर उत्तर है (नीचे की जांच करें)। –

+0

@ जोनाथनअर्केल अब नीचे नहीं है :) – Brilliand

+0

सुधार .. बीच की जांच करें! ;) –

उत्तर

48

यह बिल्कुल निर्भर करता है कि तुम क्या "ASCII" के रूप में तय कर रहे हैं, लेकिन मैं इस तरह एक प्रश्न का एक संस्करण की कोशिश कर रहा सुझाव है:

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

कि क्वेरी सभी पंक्तियों जहां columnToCheck किसी भी गैर अक्षरांकीय शामिल वापस आ जाएगी वर्ण। यदि आपके पास अन्य पात्र हैं जो स्वीकार्य हैं, तो उन्हें नियमित अभिव्यक्ति में वर्ण वर्ग में जोड़ें।

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

MySQL प्रलेखन के अधिक प्रासंगिक पृष्ठों शायद 12.5.2 Regular Expressions है: उदाहरण के लिए, यदि अवधि, अल्पविराम, और हाइफ़न ठीक कर रहे हैं, के लिए क्वेरी बदल जाते हैं।

+0

धन्यवाद - मैं इसे देख लूंगा। मुझे SQL में नियमित अभिव्यक्तियों के साथ अधिक अनुभव नहीं है, इसलिए यह सीखने का एक अच्छा अवसर होगा। –

+3

क्या आप हाइफ़न और अवधि से बच नहीं सकते हैं? (चूंकि उनके पास नियमित अभिव्यक्ति में विशेष अर्थ हैं।) चयन करें * तालिका नाम से जहां कॉलम नहीं है REGEXP '[A-Za-z0-9 \।, \ -]'; – Tooony

+2

"नहीं" "REGEXP" के सामने होना चाहिए। यह केवल मेरे लिए काम करता था जब उस जगह "नहीं" था। –

41

यह शायद आप के लिए क्या देख रहे हैं:

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

यह सभी पंक्तियों जहां स्तंभ में रखे लौटना चाहिए गैर- ASCII वर्ण (या ऐसे न्यू लाइन के रूप में प्रिंट न हो सकने ASCII वर्ण)।

+6

मेरे लिए बहुत अच्छा काम करता है। "regexp" [^ - ~] '' का अर्थ है एक चरित्र जो अंतरिक्ष से पहले है "या" ~ "या ASCII 32 - 126 के बाद। सभी अक्षरों, संख्याओं और प्रतीकों, लेकिन कोई अप्राप्य चीजें नहीं। – Josh

+0

आप इसे टी-शर्ट के रूप में भी प्राप्त कर सकते हैं;) http://www.catonmat.net/blog/my-favorite-regex/ – SamGoody

+1

** दस्तावेज़ीकरण में ** चेतावनी ** नोट करें (https://dev.mysql.com/doc/en/regexp.html): "* 'REGEXP' और' RLIKE 'ऑपरेटर बाइट-वार फैशन में काम करते हैं, इसलिए वे बहु-बाइट सुरक्षित नहीं हैं और अप्रत्याशित परिणाम बहु- बाइट चरित्र सेट।इसके अलावा, ये ऑपरेटर अपने बाइट मानों से वर्णों की तुलना करते हैं और उच्चारण वर्णों की तुलना बराबर की तुलना नहीं की जा सकती है, भले ही दिए गए कोलेक्शन उन्हें समान मानते हैं। * " – eggyal

91

आप 0 दशमलव मान है कि सभी पात्रों के रूप में ASCII परिभाषित कर सकते हैं - 127 (0x00 - 0x7F) और निम्न क्वेरी

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

का उपयोग कर गैर- ASCII वर्ण के साथ कॉलम मिलेंगे यह सबसे व्यापक क्वेरी था मैं साथ आ सकता था।

+2

अब तक का सबसे अच्छा जवाब है, लेकिन यह इस तरह से भी आसान है: 'चुनें * तालिका से जहां लेंस (कॉलम)! = CHAR_LENGTH (कॉलम) ' – SuN

+11

-1 ** यह गलत परिणाम उत्पन्न कर सकता है। ** मान लीजिए, उदाहरण के लिए, एक यू है टीएफ -16 कॉलम जिसमें '' '' (बाइट अनुक्रम '0x0101' द्वारा एन्कोड किया गया है) - इसे इस परीक्षण का उपयोग करके "ASCII" समझा जाएगा: * एक झूठी नकारात्मक *; वास्तव में, कुछ चरित्र सेट ASCII वर्णों को '0x00' से '0x7f' के भीतर एन्कोड नहीं करते हैं, जहां इस समाधान से झूठी सकारात्मक उत्पन्न होगी। ** इस उत्तर पर निर्भर न करें! ** – eggyal

+2

@sun: यह बिल्कुल मदद नहीं करता है - कई वर्ण सेट निश्चित-लंबाई हैं और इसलिए 'LENGTH (कॉलम) '' CHAR_LENGTH (कॉलम)' का निरंतर एकाधिक होगा मूल्य के बावजूद। – eggyal

150

MySQL व्यापक चरित्र सेट प्रबंधन प्रदान करता है जो इस तरह की समस्या से मदद कर सकता है।

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

CONVERT(col USING charset) कार्य करेंगे प्रतिस्थापन अक्षरों में unconvertable वर्ण बदल जाता है। फिर, रूपांतरित और अपरिवर्तित पाठ असमान होगा।

अधिक चर्चा के लिए इसे देखें। http://dev.mysql.com/doc/refman/5.7/en/charset-repertoire.html

आप ASCII के स्थान पर इच्छित किसी भी चरित्र सेट नाम का उपयोग कर सकते हैं। उदाहरण के लिए, यदि आप यह जानना चाहते हैं कि कौन से वर्ण कोड पृष्ठ 1257 (लिथुआनियाई, लातवियाई, एस्टोनियन) में सही ढंग से प्रस्तुत नहीं करेंगे, CONVERT(columnToCheck USING cp1257)

+12

यह इस समस्या का एक उत्कृष्ट समाधान है और बहुत अधिक मजबूत है। – CraigDouglas

+4

यह आरईजीईएक्सपी (जो उच्चारण खोजने के लिए मेरे लिए काम नहीं करता है) से अधिक बेहतर एन्कोडिंग – Glasnhost

+0

एन्कोडिंग से संबंधित वर्णों को खोजने के लिए उपयोगी नहीं है (और यह सब कुछ बनाने के लिए एक सरल तंत्र भी प्रदान करता है) ascii फिर से ... –

11

उपरोक्त सभी उदाहरणों से एक गायब चरित्र समाप्ति चरित्र (\ 0) है। यह MySQL कंसोल आउटपुट के लिए अदृश्य है और पहले उल्लिखित किसी भी प्रश्न से खोजने योग्य नहीं है। क्वेरी यह पता लगाने के लिए बस है:

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

यह करता है:

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

सही जवाब के आधार पर, लेकिन साथ ही खाते ASCII नियंत्रण वर्ण को ध्यान में रखकर, समाधान है कि मेरे लिए काम किया है एक ही बात: कॉलम में ASCII रेंज के उल्लंघन की खोज करता है, लेकिन आपको नियंत्रण वर्णों की भी खोज करने देता है, क्योंकि यह कोड बिंदुओं के लिए हेक्साडेसिमल नोटेशन का उपयोग करता है। चूंकि कोई तुलना या रूपांतरण नहीं है (@ ओली के उत्तर के विपरीत), यह भी काफी तेज होना चाहिए। (विशेष रूप से यदि MySQL रेगेक्स क्वेरी पर प्रारंभिक समाप्ति करता है, जो इसे निश्चित रूप से करना चाहिए।)

यह शून्य-लंबाई वाले फ़ील्ड लौटने से भी बचाता है। आप एक से थोड़ा-लंबे समय तक संस्करण है कि बेहतर प्रदर्शन कर सकते हैं चाहते हैं, तो आप इस के बजाय का उपयोग कर सकते हैं:

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

यह लंबाई से बचने के लिए शून्य लंबाई परिणाम के लिए एक अलग जांच करता है उन्हें एक regex पारित करने के लिए विचार किए बिना। आपके पास शून्य-लंबाई प्रविष्टियों की संख्या के आधार पर, यह काफी तेज़ हो सकता है।

ध्यान दें कि यदि आपका डिफ़ॉल्ट वर्ण सेट कुछ विचित्र है जहां 0x00-0xFF ASCII के समान मानों पर नक्शा नहीं लगाता है (क्या ऐसा कोई चरित्र मौजूद है?), यह झूठी सकारात्मक लौटाएगा। अन्यथा, आनंद लें!

+1

00-एफएफ में सभी संभव 8-बिट मान शामिल हैं, जो 'REGEXP' जांच रहा है। इसलिए यह हमेशा मिलान करने की गारंटी है। इसके अलावा '^ $' शायद वह नहीं है जो आप चाहते थे। –

0

@ zende का जवाब केवल एक ही है कि ascii और गैर ASCII वर्ण के मिश्रण के साथ कॉलम कवर था खोज के लिए इस क्वेरी का उपयोग करते हुए प्रयास करें, लेकिन यह भी है कि समस्याग्रस्त हेक्स बात की थी। मैंने इसका इस्तेमाल किया:

SELECT * FROM `table` WHERE NOT `column` REGEXP '^[ -~]+$' AND `column` !='' 
संबंधित मुद्दे