परिवर्तित प्रतीकों, अंग्रेजी वर्णमाला के लिए उच्चारण पत्र


129

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

उदाहरण के लिए यहां कुछ रूपांतरण दिए गए हैं:

ҥ->H
Ѷ->V
Ȳ->Y
Ǭ->O
Ƈ->C
tђє Ŧค๓เℓy --> the Family
...

और मैंने देखा कि पत्र ए / ए के 20 से अधिक संस्करण हैं। और मुझे नहीं पता कि उन्हें कैसे वर्गीकृत किया जाए। वे घास के मैदान में सुइयों की तरह दिखते हैं।

यूनिकोड चार्ट की पूरी सूची http://www.ssec.wisc.edu/~tomw/java/unicode.html या http://unicode.org/charts/charindex.html पर है । बस नीचे स्क्रॉल करने का प्रयास करें और अक्षरों की विविधताएं देखें।

मैं जावा के साथ इन सभी को कैसे बदल सकता हूं? कृपया मेरी मदद करें :(


यह प्रश्न देखें: stackoverflow.com/questions/249087/… - इस विषय के बारे में कुछ अन्य प्रश्न भी होने चाहिए, लेकिन मैं उन्हें फिलहाल नहीं खोज सकता।
श्नाडर

1
क्या आपका तीसरा उदाहरण Ȳ → Y होना चाहिए?
डोर हाई आर्क

2
तुम ऐसा क्यों करना चाहते हो? यदि हमें पता था कि आपका समग्र लक्ष्य क्या है, तो हम अधिक सहायक हो सकते हैं।
डेविड थॉर्नले

डेविड आप जानते हैं कि कुछ ईएमओ वाक्यों में विभिन्न वर्णों का उपयोग करते हैं। यहाँ आप एक उदाहरण: ฬ। t ค ђє η∂єг ¢ ђ ק ย ฬ เ ℓy <- इसे हल करें: @schnaader, मुझे लगता है कि मैं वही देख रहा हूं जो जावा में नहीं है।
अहमतबी - 20

यह वार्तालाप पहले किया गया है - ऊपर @schnaader देखें।
dkretz 20

जवाबों:


197

अपनी पोस्ट को रिपॉजिट करना। मैं .NET में स्ट्रिंग से डायक्रिटिक्स (एक्सेंट) कैसे निकालूं?

यह विधि जावा में शुद्ध रूप से काम करती है (विशुद्ध रूप से विकृति के निशान उर्फ ​​उच्चारण को हटाने के उद्देश्य से)

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

import java.text.Normalizer;
import java.util.regex.Pattern;

public String deAccent(String str) {
    String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD); 
    Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
    return pattern.matcher(nfdNormalizedString).replaceAll("");
}

4
InCombiningDiacriticalMarks सभी सिरिलिक में कनवर्ट नहीं करता है। उदाहरण के लिए Општина Богомила अछूता है। यह अच्छा होगा यदि कोई इसे Opstina Bogomila या कुछ और में बदल सकता है
iwein

13
यह बिल्कुल भी अनूदित नहीं होता है। यह केवल विघटित वर्णनात्मक निशान ("उच्चारण") को हटाता है। पिछला चरण (Form.NFD) á + + में टूट जाता है, यानी उच्चारण चरित्र को अस्वीकार्य चरित्र और साथ ही एक विशिष्ट चिह्न में बदल देता है। यह सिरिलिक ill को ill में परिवर्तित करेगा लेकिन आगे नहीं।
MSalters

1
जॉर्ज पोस्ट किया है कि यह बेहतर हो सकता है पर \\ p {भारतीय चिकित्सा पद्धति} \\ p {InCombiningDiacriticalMarks} के बजाय का उपयोग glaforge.appspot.com/article/... ध्यान दें कि मैं इसे परीक्षण नहीं किया।
अटोरस

2
\\ p {IsM} स्पेनिश लहजे की तरह काम करने के लिए प्रतीत नहीं होता है जैसे á ú ñ é é í। इसके विपरीत, "\\ p {InCombiningDiacriticalMarks} + इसके लिए अच्छा काम कर रहा है
Loic

यह सभी विशेष वर्णों के लिए काम नहीं करता है - मैंने इसके लिए Android के लिए एक गलत मुद्दा प्रस्तुत किया है कि यह जानने के लिए कि -> code.google.com/p/android/issues/detail?id=189515 कोई भी ऐसा करने का सही तरीका जानता है?
मिचेल ताजर्ट

71

यह अपाचे कॉमन्स लैंग का एक हिस्सा है । 3.0।

org.apache.commons.lang3.StringUtils.stripAccents("Añ");

रिटर्न An

Http://www.drillio.com/en/software-development/java/removing-accents-diacritics-in-any-language/ भी देखें


यह समाधान अद्भुत है। यह ग्रीक के साथ भी काम करता है! धन्यवाद।
टॉम

5
यह पोलिश वर्णों के अनुवाद के लिए एकदम सही नहीं है, जो ł और input से गायब है: इनपुट: ęąół forćao आउटपुट: SZOeaACEZaołeacnN
रॉबर्ट

1
अच्छी उपयोगिता है, लेकिन चूंकि इसका कोड बिल्कुल वैसा ही है जैसा कि स्वीकृत उत्तर में दिखाया गया है, और आप कॉमन्स लैंग पर निर्भरता नहीं जोड़ना चाहते हैं, आप सिर्फ उपरोक्त स्निपेट का उपयोग कर सकते हैं।
पोलारेतो

1
मेरे मामले में अपाचे आम के साथ:। 7-21 पर डी
होआंग

@ ह्वांग, रॉबर्ट शायद एक पुल अनुरोध भेजने का मौका :)
ओंद्र kaižka

19

"उन सभी को बदलने" का प्रयास करना समस्या का गलत तरीका है।

सबसे पहले, आपको उन सीमाओं को समझने की आवश्यकता है जो आप करने की कोशिश कर रहे हैं। जैसा कि अन्य लोगों ने बताया है, डायक्ट्रीक्स एक कारण के लिए हैं: वे अनिवार्य रूप से अपने स्वयं के अर्थ / ध्वनि आदि के साथ उस भाषा की वर्णमाला में अद्वितीय अक्षर होते हैं ।: उन निशानों को हटाना एक अंग्रेजी शब्द में यादृच्छिक अक्षरों को बदलने के समान है। इससे पहले कि आप यहां तक ​​कि सिरिलिक भाषाओं और अरबी जैसे अन्य स्क्रिप्ट आधारित ग्रंथों पर विचार करें, जिन्हें केवल अंग्रेजी में "परिवर्तित" नहीं किया जा सकता है।

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

इन तार्किक कदमों को उठाकर आप संभावित पात्रों की संख्या को उस बिंदु तक ले जा सकते हैं, जहां शब्दकोश आधारित लुकअप / रिप्लेसमेंट ऑपरेशन संभव है। इसके बाद शब्दकोशों को बनाते हुए थोड़ा उबाऊ काम होता है और प्रतिस्थापन करने के लिए एक तुच्छ कार्य होता है। यदि आपकी भाषा देशी यूनिकोड वर्णों का समर्थन करती है (जैसा कि जावा करता है) और स्थिर संरचनाओं को सही ढंग से अनुकूलित करता है, तो ऐसी खोजें और जगह जल्दी धुंधली हो जाती हैं।

यह एक ऐसे अनुप्रयोग पर काम करने के अनुभव से आता है, जिसे अंतिम उपयोगकर्ताओं को ग्रंथ सूची डेटा को खोजने की अनुमति देने की आवश्यकता होती थी, जिसमें डियाक्रिटिक वर्ण शामिल थे। लुकअप सरणियों (जैसा कि यह हमारे मामले में था) ने उत्पादन करने के लिए शायद 1 आदमी दिन लिया, सभी यूरोपीय यूरोपीय भाषाओं के लिए सभी विशेष चिह्नों को कवर करने के लिए।


जवाब देने के लिए धन्यवाद। वास्तव में मैं अरबी भाषाओं के साथ काम नहीं कर रहा हूँ या ऐसा कुछ। आप जानते हैं कि कुछ लोग डायक्ट्रीक्स को मजाकिया चरित्रों के रूप में उपयोग करते हैं और मुझे इसे उतना ही निकालना होगा जितना मैं कर सकता हूं। उदाहरण के लिए, मैंने कहा "tђє Ŧ, เ ℓ --y -> परिवार" उदाहरण में रूपांतरण लेकिन यह मुश्किल लगता है इसे पूरी तरह से परिवर्तित करें। हालांकि, हम एक सरल तरीके से "weéışöç-> oeisoc" रूपांतरण कर सकते हैं। लेकिन ऐसा करने का सटीक तरीका क्या है। सरणियाँ बनाना और मैन्युअल रूप से प्रतिस्थापित करना? या इस भाषा में इस मुद्दे के मूल कार्य हैं?
अहमत

15

चूंकि एन्कोडिंग जो "परिवार" को "tŦ ค ๓ เ ℓ thaty" में बदल देता है, प्रभावी रूप से यादृच्छिक है और किसी भी एल्गोरिथ्म का पालन नहीं कर रहा है जिसे यूनिकोड कोडपॉइंट्स की जानकारी द्वारा समझाया जा सकता है, इस एल्गोरिथम को हल करने का कोई सामान्य तरीका नहीं है।

आपको यूनिकोड वर्णों की लैटिन वर्णों में मानचित्रण बनाने की आवश्यकता होगी जो वे सदृश हैं। आप शायद यूनिकोड कोड पॉइंट्स का प्रतिनिधित्व करने वाले वास्तविक ग्लिफ़ पर कुछ स्मार्ट मशीन सीखने के साथ ऐसा कर सकते हैं। लेकिन मुझे लगता है कि इसके लिए प्रयास मैन्युअल रूप से उस मैपिंग के निर्माण से अधिक होगा। खासकर यदि आपके पास अच्छी मात्रा में उदाहरण हैं जिनसे आप अपनी मैपिंग का निर्माण कर सकते हैं।

स्पष्ट करने के लिए: कुछ प्रतिस्थापन वास्तव में यूनिकोड डेटा के माध्यम से हल किए जा सकते हैं (जैसा कि अन्य उत्तर प्रदर्शित करता है), लेकिन कुछ अक्षरों का लैटिन अक्षरों के साथ कोई उचित जुड़ाव नहीं है जो वे मिलते-जुलते हैं।

उदाहरण:

  • "" "(U + 0452 CYRILLIC SMALL LETTER DJE)" d "से अधिक" d "से संबंधित है, लेकिन इसका उपयोग" h "को दर्शाने के लिए किया जाता है।
  • "" "(U + 0166 लेटिन कैपिटल लेटर टी विद STROKE) कुछ हद तक" T "से संबंधित है (जैसा कि नाम से पता चलता है) लेकिन इसका उपयोग" F "का प्रतिनिधित्व करने के लिए किया जाता है।
  • "" "(U + 0E04 THAI CHARACTER KHO KHWAI) किसी भी लैटिन वर्ण से संबंधित नहीं है और आपके उदाहरण में" a "का प्रतिनिधित्व करने के लिए उपयोग किया जाता है

7

मूल अनुरोध पहले ही उत्तर दिया जा चुका है।

हालाँकि, मैं नीचे दिए गए उत्तर को उन लोगों के लिए पोस्ट कर रहा हूं, जो जावा में लैटिन / अंग्रेजी में किसी भी वर्णमाला को बदलने के लिए सामान्य लिप्यंतरण कोड की तलाश में हो सकते हैं।

ट्रानिटैलिट्रेशन का Naive अर्थ: यह अंतिम रूप में अनुवादित स्ट्रिंग है / यह मूल रूप में स्ट्रिंग की तरह लक्ष्य चारसेट लगता है। यदि हम लैटिन (अंग्रेजी वर्णमाला) के लिए किसी भी चार्ट को बदलना चाहते हैं, तो ICU4 (जावा में ICU4J पुस्तकालय) काम करेंगे।

यहाँ जावा में कोड स्निपेट है:

    import com.ibm.icu.text.Transliterator; //ICU4J library import

    public static String TRANSLITERATE_ID = "NFD; Any-Latin; NFC";
    public static String NORMALIZE_ID = "NFD; [:Nonspacing Mark:] Remove; NFC";

    /**
    * Returns the transliterated string to convert any charset to latin.
    */
    public static String transliterate(String input) {
        Transliterator transliterator = Transliterator.getInstance(TRANSLITERATE_ID + "; " + NORMALIZE_ID);
        String result = transliterator.transliterate(input);
        return result;
    }

7

स्ट्रिंग परीक्षण किया गया: ÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝß

परीक्षण किया गया:

अंतिम विकल्प सबसे अच्छा है।


1
@mehmet सिर्फ github.com/xuender/unidecode पर रीडमी का अनुसरण करें । यह निर्भरता को आयात करने के बाद Unidecode.decode ("ÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßÃ)") जैसा कुछ होना चाहिए।
cactuschibre

6

यदि आवश्यकता "şéışöç-> oeisoc" को बदलने की है, तो आप इसे एक प्रारंभिक बिंदु का उपयोग कर सकते हैं:

public class AsciiUtils {
    private static final String PLAIN_ASCII =
      "AaEeIiOoUu"    // grave
    + "AaEeIiOoUuYy"  // acute
    + "AaEeIiOoUuYy"  // circumflex
    + "AaOoNn"        // tilde
    + "AaEeIiOoUuYy"  // umlaut
    + "Aa"            // ring
    + "Cc"            // cedilla
    + "OoUu"          // double acute
    ;

    private static final String UNICODE =
     "\u00C0\u00E0\u00C8\u00E8\u00CC\u00EC\u00D2\u00F2\u00D9\u00F9"             
    + "\u00C1\u00E1\u00C9\u00E9\u00CD\u00ED\u00D3\u00F3\u00DA\u00FA\u00DD\u00FD" 
    + "\u00C2\u00E2\u00CA\u00EA\u00CE\u00EE\u00D4\u00F4\u00DB\u00FB\u0176\u0177" 
    + "\u00C3\u00E3\u00D5\u00F5\u00D1\u00F1"
    + "\u00C4\u00E4\u00CB\u00EB\u00CF\u00EF\u00D6\u00F6\u00DC\u00FC\u0178\u00FF" 
    + "\u00C5\u00E5"                                                             
    + "\u00C7\u00E7" 
    + "\u0150\u0151\u0170\u0171" 
    ;

    // private constructor, can't be instanciated!
    private AsciiUtils() { }

    // remove accentued from a string and replace with ascii equivalent
    public static String convertNonAscii(String s) {
       if (s == null) return null;
       StringBuilder sb = new StringBuilder();
       int n = s.length();
       for (int i = 0; i < n; i++) {
          char c = s.charAt(i);
          int pos = UNICODE.indexOf(c);
          if (pos > -1){
              sb.append(PLAIN_ASCII.charAt(pos));
          }
          else {
              sb.append(c);
          }
       }
       return sb.toString();
    }

    public static void main(String args[]) {
       String s = 
         "The result : È,É,Ê,Ë,Û,Ù,Ï,Î,À,Â,Ô,è,é,ê,ë,û,ù,ï,î,à,â,ô,ç";
       System.out.println(AsciiUtils.convertNonAscii(s));
       // output : 
       // The result : E,E,E,E,U,U,I,I,A,A,O,e,e,e,e,u,u,i,i,a,a,o,c
    }
}

JDK 1.6 java.text.Normalizer वर्ग प्रदान करता है जिसका उपयोग इस कार्य के लिए किया जा सकता है।

एक उदाहरण यहाँ देखें


दुर्भाग्य से यह Æ की तरह ligatures संभाल नहीं करेगा।
डोर हाई आर्क

यह विधि विशेष रूप से उपयोगी है यदि आपको अलग-अलग तरीके से डायक्ट्रीक्स की कक्षाओं का पता लगाने और उन्हें संभालने की आवश्यकता है (यानी, LaTXX में विशेष पात्रों से बचकर)।
vallismortis

4

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


आप इनमें से किसी एक से लुकअप टेबल प्राप्त कर सकते हैं।
कैथी वान स्टोन

यह एक अद्भुत पैकेज है, लेकिन यह चरित्र की ध्वनि को लिप्यंतरित करता है, उदाहरण के लिए यह "to" को "बेई" में परिवर्तित करता है क्योंकि यह वही है जो चरित्र मंदारिन में लगता है। मुझे लगता है कि प्रश्नकर्ता ग्लिफ़्स को उस रूप में बदलना चाहता है जो वे अंग्रेजी में देखते हैं।
डोर हाई आर्क

यह लैटिन वर्णों के लिए ऐसा करता है, हालांकि। एक बन जाता है, एट अल। @ahmetalpbalkan मैं कैथी से सहमत हूं, आप इसे अपने स्वयं के लुकअप टेबल बनाने के लिए संसाधन के रूप में उपयोग कर सकते हैं, तर्क बहुत सरल होना चाहिए। दुर्भाग्य से वहाँ एक जावा संस्करण प्रतीत नहीं होता है।
डैनियल वांडर्सलुइस

@ahmetalpbalkan यहाँ जावा के लिए यूनिडबॉरो है।
जकूब जिरुटका

4

कोई आसान या सामान्य तरीका नहीं है कि आप क्या चाहते हैं क्योंकि यह सिर्फ आपकी व्यक्तिपरक राय है कि ये पत्र उन लैटिन अक्षरों को देख लेते हैं जिन्हें आप बदलना चाहते हैं। वे वास्तव में अपने स्वयं के अलग-अलग नामों और ध्वनियों के साथ अलग-अलग पत्र हैं जो सिर्फ सतही रूप से लैटिन अक्षर की तरह दिखते हैं।

यदि आप उस रूपांतरण को चाहते हैं, तो आपको अपने स्वयं के अनुवाद तालिका का निर्माण करना होगा जो आपको लगता है कि लैटिन अक्षरों के आधार पर गैर-लैटिन अक्षरों को परिवर्तित किया जाना चाहिए।

(यदि आप केवल डियाक्रिटिकल मार्क्स को हटाना चाहते हैं, तो इस थ्रेड में कुछ उत्तर हैं: मैं .NET में स्ट्रिंग से डायक्रिटिक्स (उच्चारण) कैसे निकालूं? हालांकि आप एक अधिक सामान्य समस्या का वर्णन करते हैं।


+1। यहाँ 'निकालें डिक्टाइटरिक्स' सवाल का एक जावा संस्करण है: stackoverflow.com/questions/1016955/… ; माइकल बोर्गवर्ड और देवियो के उत्तर देखें
जोनीक

4

मुझे पार्टी में देर हो गई है, लेकिन आज इस मुद्दे का सामना करने के बाद, मुझे यह उत्तर बहुत अच्छा लगा:

String asciiName = Normalizer.normalize(unicodeName, Normalizer.Form.NFD)
    .replaceAll("[^\\p{ASCII}]", "");

संदर्भ: https://stackoverflow.com/a/16283863


छोटी चेतावनी - यह U + 00DF LATIN SMALL LETTER SHARP S "ß" को हटा देती है
rafalmag

और भी Æ ... बुरा करने के लिए।
cactuschibre

4

यूनीकोड ​​को ASCII में "परिवर्तित" करने में समस्या यह है कि एक चरित्र का अर्थ संस्कृति पर निर्भर है। उदाहरण के लिए, एक जर्मन-भाषी व्यक्ति को "to" को "ss" में परिवर्तित किया जाना चाहिए, जबकि एक अंग्रेजी-वक्ता शायद इसे "B" में बदल देगा।

इस तथ्य को जोड़ें कि यूनिकोड में एक ही ग्लिफ़ के लिए कई कोड बिंदु हैं।

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

यहाँ एक ऐप का एक छोटा सा अंश है जो यह करता है:

switch (c)
{
    case 'A':
    case '\u00C0':  //  À LATIN CAPITAL LETTER A WITH GRAVE
    case '\u00C1':  //  Á LATIN CAPITAL LETTER A WITH ACUTE
    case '\u00C2':  //  Â LATIN CAPITAL LETTER A WITH CIRCUMFLEX
    // and so on for about 20 lines...
        return "A";
        break;

    case '\u00C6'://  Æ LATIN CAPITAL LIGATURE AE
        return "AE";
        break;

    // And so on for pages...
}

मैं सहमत हूँ। आपको विशेष रूप से अपने आवेदन और अपेक्षित दर्शकों के लिए रूपांतरणों का एक शब्दकोश बनाना चाहिए। उदाहरण के लिए, स्पैनिश-भाषी श्रोताओं के लिए मैं केवल ÁÉÍÓÚÜÑáéíóúü Bon
रॉबर्टो बोनावलेट

रॉबर्टो के हजारों चरित्र हैं और मैं यह मैनुअल नहीं कर सकता।
अहमत -

2
आप किस मानव भाषा का उपयोग कर रहे हैं जिसमें "हजारों" अक्षर हैं? जापानी? आप क्या उम्मीद करेंगे कि would う ど ど ど ど ど ど ど か か को रूपांतरित किया जा सके?
डोर हाई आर्क

6
जो उदाहरण आपने दिया है वह आदर्श नहीं है: U + 00DF LATIN SMALL LETTER SHARP S "not" U + 03B2 GREEK SMALL LETTER BETA "β" के समान यूनिकोड अक्षर नहीं है।
जोकिम सॉर

2

निम्न वर्ग चाल करता है:

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