Regex: InCombiningDiacriticalMarks क्या है?


86

निम्नलिखित कोड को बहुत स्पष्ट रूप से उच्चारण वर्णों को सादे पाठ में बदलने के लिए जाना जाता है:

Normalizer.normalize(text, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");

मैंने अपनी "हाथ से बनाई गई" विधि को इस एक से बदल दिया, लेकिन मुझे प्रतिस्थापन के "रेगेक्स" भाग को समझने की आवश्यकता है

1) "InCombiningDiacriticalMarks" क्या है?
2) इसका प्रलेखन कहाँ है? (और सिमिलर?)

धन्यवाद।


यह भी देखें stackoverflow.com/a/29111105/32453 जाहिरा तौर पर सिर्फ एक नोट के रूप में, विशेषक की तुलना में यूनिकोड में अधिक "संयोजन के निशान" हैं।
रोजरपैक

जवाबों:


74

\p{InCombiningDiacriticalMarks}एक यूनिकोड ब्लॉक संपत्ति है। JDK7 में, आप इसे दो-भाग अंकन का उपयोग करके लिख पाएंगे \p{Block=CombiningDiacriticalMarks}, जो पाठक को स्पष्ट हो सकता है। इसे यहाँ UAX # 44 में लिखा गया है: "यूनिकोड कैरेक्टर डेटाबेस"

इसका मतलब यह है कि कोड बिंदु एक विशेष सीमा के भीतर आता है, एक ब्लॉक, जिसे उस नाम से चीजों के लिए उपयोग करने के लिए आवंटित किया गया है। यह एक बुरा दृष्टिकोण है, क्योंकि इस बात की कोई गारंटी नहीं है कि उस सीमा में कोड बिंदु कोई विशेष बात नहीं है, और न ही उस ब्लॉक के बाहर कोड बिंदु अनिवार्य रूप से समान वर्ण के नहीं हैं।

उदाहरण के लिए, \p{Latin_1_Supplement}ब्लॉक में लैटिन अक्षर हैं , जैसे é, U + 00E9। हालांकि, वहाँ चीजें हैं जो कर रहे हैं नहीं लातिन अक्षरों वहाँ भी। और निश्चित रूप से सभी जगह लैटिन अक्षर भी हैं।

ब्लॉक लगभग कभी भी आप क्या चाहते हैं।

इस मामले में, मुझे संदेह है कि आप संपत्ति का उपयोग करना चाह सकते हैं \p{Mn}, उर्फ \p{Nonspacing_Mark}। कॉम्बिंग_डायरेक्चुअल ब्लॉक में सभी कोड पॉइंट उस तरह के होते हैं। वहाँ भी हैं (यूनिकोड 6.0.0 के रूप में) 1087 Nonspacing_Marks जो उस ब्लॉक में नहीं हैं ।

यही कारण है कि लगभग के लिए जाँच के रूप में ही है \p{Bidi_Class=Nonspacing_Mark}, लेकिन काफी नहीं है कि समूह में भी संलग्न के निशान भी शामिल है क्योंकि, \p{Me}। यदि आप दोनों चाहते हैं, [\p{Mn}\p{Me}]तो आप कह सकते हैं कि क्या आप एक डिफ़ॉल्ट जावा रेगेक्स इंजन का उपयोग कर रहे हैं, क्योंकि यह केवल General_Category संपत्ति तक पहुँच प्रदान करता है।

ICU C ++ regex लाइब्रेरी को प्राप्त करने के लिए आपको JNI का उपयोग करना होगा जिस तरह से Google कुछ करने के लिए उपयोग करता है \p{BC=NSM}, क्योंकि अभी केवल ICU और पर्ल सभी यूनिकोड गुणों तक पहुँच प्रदान करते हैं। सामान्य जावा रेगेक्स पुस्तकालय मानक यूनिकोड गुणों के केवल एक जोड़े का समर्थन करता है। JDK7 में हालांकि यूनिकोड स्क्रिप्ट के लिए समर्थन होगा , जो कि ब्लॉक संपत्ति के लिए असीम रूप से बेहतर है। इस प्रकार आप JDK7 लिखने में कर सकते हैं \p{Script=Latin}या \p{SC=Latin}, या छोटे-कट \p{Latin}, लैटिन लिपि से किसी भी चरित्र पर प्राप्त करने के लिए। यह बहुत ही सामान्य रूप से आवश्यक है [\p{Latin}\p{Common}\p{Inherited}]

सभी पात्रों से "उच्चारण" के निशान के रूप में जो आप सोच सकते हैं उसे दूर नहीं करेंगे, इस बात का ध्यान रखें! कई ऐसे हैं जो ऐसा नहीं करेंगे। उदाहरण के लिए, आप परिवर्तित नहीं कर सकते Đ को डी या ø को कि जिस तरह से। उसके लिए, आपको उन बिंदुओं को कोड बिंदुओं को कम करने की आवश्यकता होती है, जो यूनिकोड Collation Table में समान प्राथमिक कोलाजेशन ताकत से मेल खाते हैं।

एक और जगह जहां \p{Mn}बात विफल हो जाती है, ज़ाहिर है जैसे निशान \p{Me}, जाहिर है, लेकिन ऐसे भी \p{Diacritic}चरित्र हैं जो निशान नहीं हैं। अफसोस की बात है, आपको इसके लिए पूर्ण संपत्ति समर्थन की आवश्यकता है, जिसका अर्थ है जेएनआई या तो आईसीयू या पर्ल। जावा में यूनिकोड समर्थन के साथ बहुत सारे मुद्दे हैं, मुझे डर है।

ओह रुकिए, मैं देख रहा हूं कि आप पुर्तगाली हैं। आपको तब कोई समस्या नहीं होनी चाहिए जब आप केवल पुर्तगाली पाठ के साथ काम कर रहे हों।

हालाँकि, आप वास्तव में लहजे को हटाना नहीं चाहते हैं, मैं शर्त लगाता हूं, लेकिन आप चीजों को "उच्चारण-असंवेदनशील", सही से मिलान करने में सक्षम होना चाहते हैं? यदि हां, तो आप ऐसा कर सकते हैं ICU4J (जावा के लिए ICU) संपार्श्विक वर्ग का उपयोग कर । यदि आप प्राथमिक शक्ति से तुलना करते हैं, तो उच्चारण चिह्न नहीं गिने जाएंगे। मैं यह हर समय करता हूं क्योंकि मैं अक्सर स्पेनिश पाठ की प्रक्रिया करता हूं। मेरे पास इसका एक उदाहरण है कि कैसे स्पेनिश के लिए यह करना है कि अगर आपको इसकी आवश्यकता है


इसलिए, मुझे यह मान लेना चाहिए कि पूरे वेब (और यहां तक ​​कि एसओ) में दी गई विधि एक शब्द के लिए "DeAccent" के लिए अनुशंसित नहीं है। मैंने सीधे पुर्तगाली के लिए एक सीधा कर दिया, लेकिन इस अजीब दृष्टिकोण को देखा (और जैसा आपने कहा, यह मेरे उद्देश्य के लिए काम करता है, लेकिन ऐसा आखिरी विधि ने किया!)। तो, क्या एक बेहतर "अच्छी तरह से लागू" दृष्टिकोण है जो अधिकांश परिदृश्यों को कवर करेगा? एक उदाहरण बहुत अच्छा होगा। आपके समय के लिए धन्यवाद।
मार्कोलोप्स

1
@ मार्कोलोप्स: मैं डेटा को अक्षुण्ण छोड़ रहा हूं और प्राथमिक-शक्ति तुलना करने के लिए यूनिकोड Collation Algorithm का उपयोग कर रहा हूं। इस तरह यह सिर्फ अक्षरों की तुलना करता है, लेकिन मामले और उच्चारण चिह्न दोनों को अनदेखा करता है। यह भी चीजें हैं जो की सुविधा देता है चाहिए होना इसी पत्र होना ही पत्र है, जो लहजे को हटाने सिर्फ एक पीला और करने के लिए असंतोषजनक अनुमान होता है। इसके अलावा यह डेटा को ज़ैप करने के लिए क्लीनर नहीं है यदि आप इसके साथ काम कर सकते हैं जो आप चाहते हैं, लेकिन इसकी आवश्यकता नहीं है।
1

बहुत अच्छा जवाब, एक सवाल, क्या मैं जावा में नॉर्मलाइज़र का उपयोग कर सकता हूं और InCombiningDiacriticalMarks का उपयोग कर सकता हूं, लेकिन कुछ पात्रों जैसे ü को यू में परिवर्तित करने से बाहर कर सकता हूं?
एलेक्सकॉन

6
हाँ, मैं पूरी तरह से इस सब को समझ गया हूँ
Dónal

4

मुझे कुछ समय लगा, लेकिन मैंने उन सभी को बाहर निकाल दिया:

यहाँ रेगेक्स है, जिसमें सभी जैलगो वर्णों को शामिल किया जाना चाहिए, जिनमें 'सामान्य' श्रेणी में बाईपास किया गया है।

([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F\u0483-\u0486\u05C7\u0610-\u061A\u0656-\u065F\u0670\u06D6-\u06ED\u0711\u0730-\u073F\u0743-\u074A\u0F18-\u0F19\u0F35\u0F37\u0F72-\u0F73\u0F7A-\u0F81\u0F84\u0e00-\u0eff\uFC5E-\uFC62])

आशा है कि यह आपको कुछ समय बचाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.