क्या लहजे से छुटकारा पाने और पूरे स्ट्रिंग को नियमित अक्षरों में बदलने का एक तरीका है?


263

क्या लहजे से छुटकारा पाने और उन अक्षरों को नियमित करने के अलावा String.replaceAll()विधि का उपयोग करने और एक-एक करके अक्षरों को बदलने का एक बेहतर तरीका है ? उदाहरण:

इनपुट: orčpžsíáýd

आउटपुट: orcpzsiayd

यह रूसी वर्णमाला या चीनी एक जैसे लहजे के साथ सभी पत्रों को शामिल करने की आवश्यकता नहीं है।

जवाबों:


387

java.text.Normalizerआपके लिए इसे संभालने के लिए उपयोग करें ।

string = Normalizer.normalize(string, Normalizer.Form.NFD);
// or Normalizer.Form.NFKD for a more "compatable" deconstruction 

इससे सभी उच्चारण चिह्न वर्णों से अलग हो जाएंगे। फिर, आपको बस एक अक्षर होने के खिलाफ प्रत्येक वर्ण की तुलना करने और उन लोगों को बाहर फेंकने की ज़रूरत है जो नहीं हैं।

string = string.replaceAll("[^\\p{ASCII}]", "");

यदि आपका पाठ यूनिकोड में है, तो आपको इसके बजाय इसका उपयोग करना चाहिए:

string = string.replaceAll("\\p{M}", "");

यूनिकोड के लिए, \\P{M}बेस ग्लिफ़ से मेल खाता है और \\p{M}(निचला) प्रत्येक उच्चारण से मेल खाता है।

महान यूनिकोड गाइड के लिए पॉइंटर और नियमित- expressions.info के लिए गैरेटविलसन का धन्यवाद ।


7
यह हर बार नियमित अभिव्यक्ति को संकलित करता है, जो ठीक है यदि आपको केवल एक बार इसकी आवश्यकता है, लेकिन यदि आपको बहुत सारे पाठ के साथ ऐसा करने की आवश्यकता है, तो रेगेक्स को पूर्व-संकलन करना एक जीत है।
डेविड कॉनराड

3
ध्यान दें कि सभी लैटिन-आधारित अक्षर ASCII + लहजे से विघटित नहीं होते हैं। यह जैसे मार डालेगा। पोलिश में इस्तेमाल "लैटिन {पूंजी, छोटे} पत्र एल स्ट्रोक के साथ"।
माइकल पोलित्स्की

12
यह एक अच्छा दृष्टिकोण है, लेकिन सभी गैर-एएससीआईआई पात्रों को हटाना ओवरकिल है और संभवतः उन चीजों को हटा देगा जो आप नहीं चाहते हैं, जैसा कि अन्य ने संकेत दिया है। सभी यूनिकोड "निशान" को निकालना बेहतर होगा; नॉन-स्पेसिंग मार्क्स, स्पेसिंग / कॉम्बिनेशन मार्क्स और इन्क्लोजिंग मार्क्स सहित। आप इसके साथ कर सकते हैं string.replaceAll("\\p{M}", "")। अधिक जानकारी के लिए regular-expressions.info/unicode.html देखें ।
गैरेट विल्सन

4
आप शायद NFD के बजाय Normalizer.Form.NFKD का उपयोग करना चाहते हैं - NFKD ligatures जैसी चीजों को ascii वर्णों (जैसे fi से फाई) में परिवर्तित कर देगा, NFD ऐसा नहीं करेगा।
वक्ष

2
@ chesterm8, दिलचस्प रूप से NFKD "" "को" Fi "में परिवर्तित कर रहा है, लेकिन यह" "" को "AE" में परिवर्तित नहीं कर रहा है। मुझे लगता है कि मुझे पता लगाने के लिए यूनिकोड डेटा को लाना होगा, लेकिन यह वह नहीं था जिसकी मुझे उम्मीद थी।
गैरेट विल्सन

136

2011 के अनुसार आप Apache Commons StringUtils.stripAccents (इनपुट) (3.0 से) का उपयोग कर सकते हैं :

    String input = StringUtils.stripAccents("Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ");
    System.out.println(input);
    // Prints "This is a funky String"

ध्यान दें:

स्वीकृत उत्तर (एरिक रॉबर्टसन की) Ł या rick के लिए काम नहीं करता है। Apache Commons 3.5 Ø के लिए भी काम नहीं करता है, लेकिन यह doesn't के लिए काम करता है। Ø के लिए विकिपीडिया लेख पढ़ने के बाद , मुझे यकीन नहीं है कि इसे "ओ" से बदल दिया जाना चाहिए: यह नार्वेजियन और डेनिश में एक अलग पत्र है, "z" के बाद वर्णानुक्रम में। यह "स्ट्रिप एक्सेंट" दृष्टिकोण की सीमाओं का एक अच्छा उदाहरण है।


2
मैं देख रहा हूं कि there , @KarolS के लिए एक खुली बग रिपोर्ट है । किसी ने एक पुल अनुरोध प्रस्तुत किया, लेकिन यह कुछ परीक्षणों में विफल रहा और पिछले वर्ष के जुलाई से इसे अपडेट नहीं किया गया।
डेविड्स

1
5 दिन पहले इस पर अद्यतन किया गया था और पुल अनुरोध को विलय कर दिया गया था।
एपिकपांडाफॉर्स

6
कॉमन्स लैंग 3.5 को कई दिनों पहले जारी किया गया था। मैंने पुष्टि की कि यह अब on पर काम करता है। यह doesn't पर काम नहीं करता है। के लिए विकी लेख को पढ़ने के , मुझे यकीन है कि यह "ओ" के साथ प्रतिस्थापित किया जाना चाहिए नहीं कर रहा हूँ: यह एक है अलग पत्र नार्वे और डेनमार्क में, "Z" के बाद alphabetized। यह "स्ट्रिप एक्सेंट" दृष्टिकोण की सीमाओं का एक अच्छा उदाहरण है।
डेविड 13

2
यदि आप लाइब्रेरी को शामिल नहीं करना चाहते हैं, तो आप उस सुविधा में शामिल दो विधियों को commons.apache.org/proper/commons-lang/apidocs/src-html/org/…
lujop

2
डेन के रूप में, डेनिश / नार्वेजियन ø सिर्फ फ्रेंच the और जर्मन / स्वीडिश / हंगेरियन / एस्टोनियाई आदि के रूप में ö ओई लिखने के लिए एक छोटा तरीका है। इसलिए आपके उद्देश्य के आधार पर यह वह स्थानापन्न हो सकता है जिसे आप चाहते हैं।
ओले वीवी

57

@ Virgo47 द्वारा समाधान बहुत तेज़ है, लेकिन अनुमानित है। स्वीकृत उत्तर नॉर्मलाइज़र और एक नियमित अभिव्यक्ति का उपयोग करता है। मैं सोचता था कि नॉर्मलाइज़र बनाम नियमित अभिव्यक्ति द्वारा समय का कौन सा हिस्सा लिया गया था, क्योंकि सभी गैर-एएससीआईआई पात्रों को हटाने से रेगेक्स के बिना किया जा सकता है:

import java.text.Normalizer;

public class Strip {
    public static String flattenToAscii(String string) {
        StringBuilder sb = new StringBuilder(string.length());
        string = Normalizer.normalize(string, Normalizer.Form.NFD);
        for (char c : string.toCharArray()) {
            if (c <= '\u007F') sb.append(c);
        }
        return sb.toString();
    }
}

छोटे अतिरिक्त स्पीड-अप्स को चार [] में लिखकर प्राप्त किया जा सकता है और कॉलचार्ज () को कॉल नहीं किया जा सकता है, हालांकि मुझे यकीन नहीं है कि कोड स्पष्टता में कमी यह गुण है:

public static String flattenToAscii(String string) {
    char[] out = new char[string.length()];
    string = Normalizer.normalize(string, Normalizer.Form.NFD);
    int j = 0;
    for (int i = 0, n = string.length(); i < n; ++i) {
        char c = string.charAt(i);
        if (c <= '\u007F') out[j++] = c;
    }
    return new String(out);
}

इस भिन्नता में नॉर्मलाइज़र का उपयोग करने वाले की शुद्धता का लाभ है और तालिका का उपयोग करने वाले की गति में से कुछ की। मेरी मशीन पर, यह स्वीकार किए गए उत्तर की तुलना में लगभग 4 गुना तेज है, और 6.6x से 7x धीमा है कि @ virgo47 (स्वीकृत उत्तर मेरे मशीन पर @ virgo47 की तुलना में लगभग 26x धीमा है)।


2
outjस्ट्रिंग ऑब्जेक्ट के निर्माण के लिए उपयोग किए जाने से पहले वैध वर्णों की संख्या से मेल खाने के लिए इसका आकार बदला जाना चाहिए ।
लेफ्टिस E

4
मुझे इस समाधान पर आपत्ति है। "Inputøåá" इनपुट की कल्पना करें। वर्तमान flattenToAsciiपरिणाम "आ .." बनाता है जहाँ डॉट्स \ u0000 का प्रतिनिधित्व करते हैं। वह ठीक नहीं है। पहला सवाल है - "अस्वाभाविक" पात्रों का प्रतिनिधित्व कैसे करें? मान लें कि यह होगा, या हम NULL char को वहां छोड़ सकते हैं, लेकिन किसी भी स्थिति में हमें इनमें से सही स्थिति को संरक्षित करना होगा (जैसे regex समाधान करता है)। इसके लिए यदि लूप में कुछ होना चाहिए: if (c <= '\u007F') out[j++] = c; else if (Character.isLetter(c)) out[j++] = '?';यह इसे थोड़ा धीमा कर देगा, लेकिन यह पहली जगह में सही होना चाहिए। ;-)
virgo47

मेरी अंतिम टिप्पणी को एड करें (बहुत बुरा वे अधिक समय तक नहीं रह सकते) - शायद सकारात्मक लेना ( isLetter) सही नहीं है, लेकिन मुझे बेहतर नहीं मिला। मैं यूनिकोड विशेषज्ञ नहीं हूं, इसलिए मुझे नहीं पता कि मूल चरित्र को बदलने वाले एकल चरित्र के वर्ग को बेहतर तरीके से कैसे पहचाना जाए। अधिकांश अनुप्रयोगों / उपयोगों के लिए पत्र ठीक काम करते हैं।
virgo47

1
आप शायद NFD के बजाय Normalizer.Form.NFKD का उपयोग करना चाहते हैं - NFKD ligatures जैसी चीजों को ascii वर्णों (जैसे fi से फाई) में परिवर्तित कर देगा, NFD ऐसा नहीं करेगा।
वक्ष

2
हमारे लिए हम चरित्र को पूरी तरह से हटाना चाहते थे। यह सुनिश्चित करने के लिए कि अशक्त वर्ण नहीं थे, मैंने उन्हें एक वैकल्पिक स्ट्रिंग निर्माता के साथ हटा दिया: नया स्ट्रिंग लौटाएँ (बाहर, 0, j);
माइक समरस

30

संपादित करें: यदि आप जावा <6 के साथ अटक नहीं हैं और गति महत्वपूर्ण नहीं है और / या अनुवाद तालिका बहुत सीमित है, तो डेविड द्वारा उत्तर का उपयोग करें। बिंदु का उपयोग Normalizerलूप के अंदर अनुवाद तालिका के बजाय (जावा 6 में पेश किया गया) है।

हालांकि यह "सही" समाधान नहीं है, यह तब अच्छी तरह से काम करता है जब आप रेंज जानते हैं (हमारे मामले में लैटिन 1,2), जावा 6 से पहले काम किया (हालांकि एक वास्तविक मुद्दा नहीं है) और सबसे सुझाए गए संस्करण (हो सकता है या हो सकता है) की तुलना में बहुत तेज है एक मुद्दा नहीं है):

    /**
 * Mirror of the unicode table from 00c0 to 017f without diacritics.
 */
private static final String tab00c0 = "AAAAAAACEEEEIIII" +
    "DNOOOOO\u00d7\u00d8UUUUYI\u00df" +
    "aaaaaaaceeeeiiii" +
    "\u00f0nooooo\u00f7\u00f8uuuuy\u00fey" +
    "AaAaAaCcCcCcCcDd" +
    "DdEeEeEeEeEeGgGg" +
    "GgGgHhHhIiIiIiIi" +
    "IiJjJjKkkLlLlLlL" +
    "lLlNnNnNnnNnOoOo" +
    "OoOoRrRrRrSsSsSs" +
    "SsTtTtTtUuUuUuUu" +
    "UuUuWwYyYZzZzZzF";

/**
 * Returns string without diacritics - 7 bit approximation.
 *
 * @param source string to convert
 * @return corresponding string without diacritics
 */
public static String removeDiacritic(String source) {
    char[] vysl = new char[source.length()];
    char one;
    for (int i = 0; i < source.length(); i++) {
        one = source.charAt(i);
        if (one >= '\u00c0' && one <= '\u017f') {
            one = tab00c0.charAt((int) one - '\u00c0');
        }
        vysl[i] = one;
    }
    return new String(vysl);
}

32bit JDK के साथ मेरे HW पर टेस्ट से पता चलता है कि यह àèéťš HWč89FDst से aeelstc89FDC तक 1 मिलियन गुणा ~ 100ms में रूपांतरण करता है जबकि नॉर्मलाइज़र तरीका 3.7 (37x धीमा) में बनाता है। यदि आपकी ज़रूरतें प्रदर्शन के आसपास हैं और आप इनपुट रेंज जानते हैं, तो यह आपके लिए हो सकता है।

का आनंद लें :-)


1
सुझाए गए संस्करण की बहुत अधिक सुस्ती नियमित अभिव्यक्ति के कारण है, नॉर्मलाइज़र की नहीं। नॉर्मलाइज़र का उपयोग करना लेकिन गैर-ASCII वर्णों को 'हाथ से निकालना' तेज़ है, हालांकि अभी भी आपके संस्करण के रूप में तेज़ नहीं है। लेकिन यह सभी के लिए काम करता है यूनिकोड के बजाय सिर्फ लैटिन 1 और लैटिन 2।
डेविड कॉनराड

मैंने अधिक वर्णों के साथ काम करने के लिए इसका विस्तार किया, pastebin.com/FAAm6a2j , ध्यान दें कि यह मल्टीकार अक्षर जैसे characters (DZ) के साथ सही ढंग से काम नहीं करेगा। यह इसमें से केवल 1 चरित्र का निर्माण करेगा। इसके अलावा मेरा कार्य तार के बजाय चार का उपयोग करता है, जो तेज है यदि आप चार रास्ते को संभाल रहे हैं, तो आपको कन्वर्ट करने की आवश्यकता नहीं है।
जेम्स टी

अरे मुझे समझ नहीं आ रहा है कि tab00c0 फ़ील्ड स्टैंड पर वे कौन से अक्षर हैं? उदाहरण के लिए "AAAAAAACEEEEIIII" या "lLlNnNnNnnNnOoOo" आदि ने उन्हें पहले कभी नहीं देखा था। ये आपको कहां से मिले? इसके अलावा, आप सिर्फ कोडिंग कोड का उपयोग क्यों नहीं करते हैं?
थानोसफिशरमैन

@ थानोसएफ केवल कोड के माध्यम से जाने की कोशिश करता है (यदि आवश्यक हो तो डिबगर के साथ)। यह स्ट्रिंग के प्रत्येक वर्ण के लिए क्या करता है: "क्या यह वर्ण \ u00c0 और \ u017f के बीच है? यदि हां, तो इसे तालिका से 7bit ASCII वर्ण से बदलें।" तालिका में उनके 7bit समकक्षों के साथ सिर्फ दो एन्कोडिंग पृष्ठ (लैटिन 1 और 2) शामिल हैं। इसलिए यदि यह कोड \ u00e0 (à) के साथ वर्ण है तो यह तालिका के 32 वें स्थान (e0-c0 = 32) से इसकी 7 बिट सन्निकटन लेगा - यह "a" है। कुछ वर्ण अक्षर नहीं हैं, जिन्हें उनके कोड के साथ वहां छोड़ दिया गया है।
virgo47

आपके व्याख्या के लिये धन्यवाद। मुझे वे एन्कोडिंग पृष्ठ कहां मिल सकते हैं ताकि मैं इस चर को अपनी भाषा में विस्तारित कर सकूं? (ग्रीक) स्वीकृत उत्तर पहले से ही काम करता है जो कि ग्रीक उच्चारण पत्रों की जगह लेता है लेकिन मैं आपकी विधि को भी आज़माना चाहता था और कुछ बेंचमार्क भी चलाना चाहता था :)
ThanosFisherman

22
System.out.println(Normalizer.normalize("àèé", Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""));

मेरे लिए काम किया। ऊपर स्निपेट का आउटपुट "ऐ" देता है जो कि मैं चाहता था, लेकिन

System.out.println(Normalizer.normalize("àèé", Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", ""));

कोई प्रतिस्थापन नहीं किया।


1
इसकी पुष्टि करते हुए ... आम तौर पर ASCII ठीक काम करता है, लेकिन मुझे लिनक्स (64b) पर JRockit (1.6.0_29 64b) के साथ इस समस्या का सामना करना पड़ा। किसी भी अन्य सेटअप के साथ इसकी पुष्टि नहीं कर सकते, उस पुष्टिकरण की पुष्टि नहीं कर सकते हैं, लेकिन मैं पुष्टि कर सकता हूं कि अन्य सुझाए गए समाधान ने काम किया है और इसके लिए मैं इसे एक वोट देता हूं। :-) (BTW: इसने कुछ प्रतिस्थापन किया, लेकिन पर्याप्त नहीं, इसने but को यू के लिए बदल दिया, लेकिन á to a नहीं।)
virgo47

1
आप शायद NFD के बजाय Normalizer.Form.NFKD का उपयोग करना चाहते हैं - NFKD ligatures जैसी चीजों को ascii वर्णों (जैसे fi से फाई) में परिवर्तित कर देगा, NFD ऐसा नहीं करेगा।
वक्ष

@KarolS मैं उनमें से नहीं दिखाई शामिल करने वाली लहजे
EIS

@eis एक अक्षर के पार एक स्लैश को एक डियाक्रिटिक के रूप में गिना जाता है: en.wikipedia.org/wiki/Diacritic और यदि आप उस विकिपीडिया पृष्ठ पर "उच्चारण" की एक सख्त परिभाषा से जाते हैं, तो डिसैसिस एक उच्चारण नहीं है, इसलिए निको का जवाब है अभी भी गलत है।
करोल एस

6

भाषा के आधार पर, उन लोगों को उच्चारण नहीं माना जा सकता है (जो अक्षर की ध्वनि को बदलते हैं), लेकिन विशेषांक

https://en.wikipedia.org/wiki/Diacritic#Languages_with_letters_containing_diacritics

"बोस्नियाई और क्रोएशियाई के पास č, ć,, š और ž के प्रतीक हैं, जिन्हें अलग-अलग अक्षर माना जाता है और उन्हें शब्दकोशों और अन्य संदर्भों में ऐसे सूचीबद्ध किया जाता है जिसमें शब्द वर्णानुक्रम के अनुसार सूचीबद्ध होते हैं।"

उन्हें हटाना स्वाभाविक रूप से शब्द के अर्थ को बदल सकता है, या अक्षरों को पूरी तरह से अलग-अलग में बदल सकता है।


5
माना। उदाहरण के लिए सनी में: "होरा" (सुनें) -> "होरा" (वेश्या)
क्रिस्टोफर हम्मरस्ट्रॉम

14
इससे कोई फर्क नहीं पड़ता कि उनका क्या मतलब है। सवाल यह है कि उन्हें कैसे हटाया जाए।
एरिक रॉबर्टसन

7
Erick: यह मायने रखता है कि वे क्या कहते हैं। यदि प्रश्न पूछता है कि लहजे को कैसे हटाया जाए, और यदि वे लहजे नहीं हैं, तो इसका उत्तर सिर्फ यह नहीं हो सकता कि उन सभी चीजों को कैसे हटाया जाए जो लहजे की तरह दिखते हैं। हालांकि यह शायद एक टिप्पणी होनी चाहिए और जवाब नहीं।
स्मिग

4
मुझे लगता है कि इसके लिए सामान्य उपयोग का मामला विशेष रूप से मिश्रित भाषाओं की खोज है, अक्सर इनपुट के रूप में एक अंग्रेजी कीबोर्ड के साथ, इस मामले में गलत नकारात्मक की तुलना में झूठी सकारात्मक प्राप्त करना बेहतर होता है।
nilskp

3

मैंने स्ट्रिंग्स समानता जांच से संबंधित एक ही मुद्दे का सामना किया है, तुलनात्मक स्ट्रिंग में से एक में ASCII वर्ण कोड 128-255 है

यानी, नॉन-ब्रेकिंग स्पेस - [हेक्स - ए 0] स्पेस [हेक्स - 20]। HTML पर नॉन-ब्रेकिंग स्पेस दिखाने के लिए। मैंने निम्नलिखित का उपयोग किया है spacing entities। उनका चरित्र और उसकी बाइट्स जैसी हैं&emsp is very wide space[ ]{-30, -128, -125}, &ensp is somewhat wide space[ ]{-30, -128, -126}, &thinsp is narrow space[ ]{32} , Non HTML Space {}

String s1 = "My Sample Space Data", s2 = "My Sample Space Data";
System.out.format("S1: %s\n", java.util.Arrays.toString(s1.getBytes()));
System.out.format("S2: %s\n", java.util.Arrays.toString(s2.getBytes()));

बाइट्स में आउटपुट:

S1: [77, 121, 3283, 97, 97, 109, 112, 108, 101, 3283, 112, 97, 97, 99, 101 32, 68, 97, 116, 97] S2: [77, 121 -30, -128, -125, 83, 97, 109, 112, 108, 101, -30, -128, -12583, 112, 97, 99, 101 -30, -128, -125, 68, 97, 116, 97]

विभिन्न रिक्त स्थान और उनके बाइट-कोड के लिए नीचे दिए गए कोड का उपयोग करें: wiki for List_of_Unicode_characters

String spacing_entities = "very wide space,narrow space,regular space,invisible separator";
System.out.println("Space String :"+ spacing_entities);
byte[] byteArray = 
    // spacing_entities.getBytes( Charset.forName("UTF-8") );
    // Charset.forName("UTF-8").encode( s2 ).array();
    {-30, -128, -125, 44, -30, -128, -126, 44, 32, 44, -62, -96};
System.out.println("Bytes:"+ Arrays.toString( byteArray ) );
try {
    System.out.format("Bytes to String[%S] \n ", new String(byteArray, "UTF-8"));
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
  • जावा के लिए यूनिकोड स्ट्रिंग का ➩ ASCII लिप्यंतरण। unidecode

    String initials = Unidecode.decode( s2 );
  • ➩ का उपयोग Guava: Google कोर Libraries for Java

    String replaceFrom = CharMatcher.WHITESPACE.replaceFrom( s2, " " );

    स्थान के उपयोग के लिए URL एनकोड के लिए अमरूद का उपयोग करें।

    String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);
  • String.replaceAll()कुछ के साथ इस्तेमाल होने वाली इस समस्या को दूर करने के लिए RegularExpression

    // \p{Z} or \p{Separator}: any kind of whitespace or invisible separator.
    s2 = s2.replaceAll("\\p{Zs}", " ");
    
    
    s2 = s2.replaceAll("[^\\p{ASCII}]", " ");
    s2 = s2.replaceAll(" ", " ");
  • ➩ का उपयोग java.text.Normalizer.Form । यह एनम चार यूनिकोड सामान्यीकरण रूपों के स्थिरांक प्रदान करता है जो यूनिकोड मानक अनुलग्नक # 15 में वर्णित हैं - यूनिकोड सामान्यीकरण फॉर्म और उन्हें एक्सेस करने के दो तरीके।

    यहां छवि विवरण दर्ज करें

    s2 = Normalizer.normalize(s2, Normalizer.Form.NFKC);

परीक्षण स्ट्रिंग और ➩ Unidecode, नॉर्मलाइज़र, की तरह अलग अलग दृष्टिकोण पर आउटपुट StringUtils

String strUni = "Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ Æ,Ø,Ð,ß";

// This is a funky String AE,O,D,ss
String initials = Unidecode.decode( strUni );

// Following Produce this o/p: Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ Æ,Ø,Ð,ß
String temp = Normalizer.normalize(strUni, Normalizer.Form.NFD);
Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
temp = pattern.matcher(temp).replaceAll("");

String input = org.apache.commons.lang3.StringUtils.stripAccents( strUni );

यूनीडबॉस का उपयोग करना है best choice, मेरा अंतिम कोड नीचे दिखाया गया है।

public static void main(String[] args) {
    String s1 = "My Sample Space Data", s2 = "My Sample Space Data";
    String initials = Unidecode.decode( s2 );
    if( s1.equals(s2)) { //[ , ] %A0 - %2C - %20 « http://www.ascii-code.com/
        System.out.println("Equal Unicode Strings");
    } else if( s1.equals( initials ) ) {
        System.out.println("Equal Non Unicode Strings");
    } else {
        System.out.println("Not Equal");
    }

}

3

मेरा सुझाव है Junidecode । यह न केवल Ł Ł ’और, '' को संभालेगा, बल्कि यह अन्य वर्णमाला, जैसे चीनी, से लैटिन वर्णमाला में भी स्थानांतरित करने के लिए अच्छी तरह से काम करता है।


1
होनहार लग रहा है, लेकिन मैं चाहता हूं कि यह एक अधिक सक्रिय / बनाए रखा गया प्रोजेक्ट था और मावेन पर उपलब्ध था।
फिल

2

@ दाविद कॉनराड समाधान सबसे तेज़ है जो मैंने नॉर्मलाइज़र का उपयोग करने की कोशिश की, लेकिन इसमें बग नहीं है। यह मूल रूप से ऐसे स्ट्रिप्स अक्षर हैं जो उच्चारण नहीं हैं, उदाहरण के लिए चीनी अक्षर और æ जैसे अन्य अक्षर, सभी छीन लिए गए हैं। जिन वर्णों को हम स्ट्रिप करना चाहते हैं, वे गैर रिक्ति चिह्न हैं, जो वर्ण अंतिम स्ट्रिंग में अतिरिक्त चौड़ाई नहीं लेते हैं। ये शून्य चौड़ाई वर्ण मूल रूप से किसी अन्य वर्ण में संयुक्त होते हैं। यदि आप उन्हें एक चरित्र के रूप में अलग-थलग देख सकते हैं, उदाहरण के लिए इस `, मेरा अनुमान है कि यह अंतरिक्ष चरित्र के साथ संयुक्त है।

public static String flattenToAscii(String string) {
    char[] out = new char[string.length()];
    String norm = Normalizer.normalize(string, Normalizer.Form.NFD);

    int j = 0;
    for (int i = 0, n = norm.length(); i < n; ++i) {
        char c = norm.charAt(i);
        int type = Character.getType(c);

        //Log.d(TAG,""+c);
        //by Ricardo, modified the character check for accents, ref: http://stackoverflow.com/a/5697575/689223
        if (type != Character.NON_SPACING_MARK){
            out[j] = c;
            j++;
        }
    }
    //Log.d(TAG,"normalized string:"+norm+"/"+new String(out));
    return new String(out);
}

1

यदि आपके पास कोई पुस्तकालय नहीं है, तो regex और Normalizer का उपयोग करने का सबसे अच्छा तरीका है:

    public String flattenToAscii(String s) {
                if(s == null || s.trim().length() == 0)
                        return "";
                return Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("[\u0300-\u036F]", "");
}

यह प्रतिस्थापन ("[^ \ p {ASCII}]", "")) की तुलना में अधिक कुशल है और अगर आपको डियाट्रिटिक्स (सिर्फ आपके उदाहरण की तरह) की आवश्यकता नहीं है

अन्यथा, आपको p {ASCII} पैटर्न का उपयोग करना होगा।

सादर।


0

मुझे लगता है कि सबसे अच्छा समाधान प्रत्येक वर्ण को एचईएक्स में परिवर्तित कर रहा है और इसे अन्य एचईएक्स के साथ बदल देगा। इसका कारण यह है कि 2 यूनिकोड टाइपिंग हैं:

Composite Unicode
Precomposed Unicode

उदाहरण के लिए, कम्पोजिट यूनिकोड द्वारा लिखित "example", प्रिकॉम्स्ड यूनिकोड द्वारा लिखे गए "written" से अलग है। आप मेरे नमूना वर्णों की प्रतिलिपि बना सकते हैं और अंतर देखने के लिए उन्हें परिवर्तित कर सकते हैं।

In Composite Unicode, "Ồ" is combined from 2 char: Ô (U+00d4) and ̀ (U+0300)
In Precomposed Unicode, "Ồ" is single char (U+1ED2)

मैंने कुछ बैंकों के लिए यह सुविधा विकसित की है कि वे इसे कोर-बैंक (आमतौर पर यूनिकोड का समर्थन न करें) में भेजने से पहले जानकारी को रूपांतरित करें और इस मुद्दे का सामना तब करें जब अंतिम यूजर्स डेटा को इनपुट करने के लिए कई यूनिकोड टाइपिंग का उपयोग करें। इसलिए मुझे लगता है, एचईएक्स को बदलना और इसे बदलना सबसे विश्वसनीय तरीका है।


-1

यदि कोई कोटलिन में ऐसा करने के लिए संघर्ष कर रहा है, तो यह कोड एक आकर्षण की तरह काम करता है। विसंगतियों से बचने के लिए मैं भी .toUpperCase और ट्रिम () का उपयोग करता हूं। तब मैंने यह समारोह डाला:

   fun stripAccents(s: String):String{

   if (s == null) {
      return "";
   }

val chars: CharArray = s.toCharArray()

var sb = StringBuilder(s)
var cont: Int = 0

while (chars.size > cont) {
    var c: kotlin.Char
    c = chars[cont]
    var c2:String = c.toString()
   //these are my needs, in case you need to convert other accents just Add new entries aqui
    c2 = c2.replace("Ã", "A")
    c2 = c2.replace("Õ", "O")
    c2 = c2.replace("Ç", "C")
    c2 = c2.replace("Á", "A")
    c2 = c2.replace("Ó", "O")
    c2 = c2.replace("Ê", "E")
    c2 = c2.replace("É", "E")
    c2 = c2.replace("Ú", "U")

    c = c2.single()
    sb.setCharAt(cont, c)
    cont++

}

return sb.toString()

}

इन फन का उपयोग करने के लिए कोड को इस तरह डालें:

     var str: String
     str = editText.text.toString() //get the text from EditText
     str = str.toUpperCase().trim()

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