অ্যাকসেন্টগুলি থেকে মুক্তি পাওয়ার এবং পুরো স্ট্রিংকে নিয়মিত অক্ষরে রূপান্তর করার কোনও উপায় কি?


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}(ছোট হাতের সাথে) প্রতিটি অ্যাকসেন্টের সাথে মেলে।

পয়েন্টারটির জন্য গ্যারেট উইলসনকে ধন্যবাদ এবং দুর্দান্ত ইউনিকোড গাইডের জন্য নিয়মিত- এক্সপ্রেসনস.ইনফো


7
এটি প্রতিবার নিয়মিত প্রকাশকে সংকলন করে, যা যদি আপনার কেবল একবার প্রয়োজন হয় তবে তা ঠিক আছে, তবে আপনাকে যদি অনেক পাঠ্য দিয়ে এটি করতে হয় তবে রেজেক্সকে প্রাক-সংকলন করা একটি জয়।
ডেভিড কনরাড

3
নোট করুন যে সমস্ত লাতিন-ভিত্তিক চিঠিগুলি ASCII + অ্যাকসেন্টগুলিতে পচে না। এটি যেমন হত্যা করবে। পোলিশ ভাষায় "ল্যাটিন {মূলধন, স্ট্রোক সহ ছোট} বর্ণের এল" used
মিশা পলিটোভস্কি

12
এটি একটি ভাল পন্থা, তবে সমস্ত ASCII অক্ষর মুছে ফেলা অত্যধিক দক্ষ এবং অন্যেরা যেমন সূচিত করেছে, সম্ভবত আপনি যা চান না এমন জিনিসগুলি সরিয়ে ফেলবেন। সমস্ত ইউনিকোড "চিহ্ন" অপসারণ করা ভাল; ব্যবধানহীন চিহ্ন, ব্যবধান / সংমিশ্রণ চিহ্ন এবং সংযুক্তি চিহ্ন সহ। আপনি এটি দিয়ে এটি করতে পারেন string.replaceAll("\\p{M}", "")। আরও তথ্যের জন্য নিয়মিত- এক্সপ্রেসন.ইন.ফো / ইউনিকোডHtml দেখুন ।
গ্যারেট উইলসন

4
আপনি সম্ভবত এনএফডি-র পরিবর্তে নরমালাইজার.ফর্ম.এনএফকেডি ব্যবহার করতে চান - এনএফকেডি লিগ্যাচারের মতো জিনিসকে এসকিআই অক্ষরে রূপান্তরিত করবে (উদাহরণস্বরূপ fi ফাইতে), এনএফডি এটি করবে না।
চেস্টার্ম 8

2
@ চেস্টারম 8, আকর্ষণীয়ভাবে এনএফকেডি "fi" কে "ফাই" তে রূপান্তর করছে, তবে এটি "Æ" কে "এই" তে রূপান্তর করছে না। আমার ধারণা আমি কেন ইউনিকোড ডেটা আনতে হবে তা জানতে, তবে এটি আমার প্রত্যাশা ছিল না।
গ্যারেট উইলসন

136

২০১১ সালের হিসাবে আপনি অ্যাপাচি কমন্স স্ট্রিংইটিলস.স্ট্রিপএ্যাকসেন্টস (ইনপুট) ব্যবহার করতে পারেন (৩.০ থেকে):

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

বিঃদ্রঃ:

গৃহীত উত্তর (এরিক রবার্টসনের) Ø বা for এর জন্য কাজ করে না Ł অ্যাপাচি কমন্স 3.5 কোনওটির জন্যই কাজ করে না, তবে এটি Ł এর জন্য কাজ করে Ł উইকিপিডিয়া নিবন্ধটি Ø এর জন্য পড়ার পরে , আমি নিশ্চিত নই যে এটি "ও" দিয়ে প্রতিস্থাপন করা উচিত: এটি নরওয়েজিয়ান এবং ডেনিশ ভাষায় একটি পৃথক চিঠি, "জেড" এর পরে বর্ণমালা হয়েছে। এটি "স্ট্রিপ অ্যাকসেন্টস" পদ্ধতির সীমাবদ্ধতার একটি ভাল উদাহরণ।


2
আমি দেখতে পাচ্ছি যে ol, @ কারোলস-এর জন্য একটি ওপেন বাগ রিপোর্ট রয়েছে। কেউ একটি টানার অনুরোধ জমা দিয়েছেন, তবে এটি কয়েকটি পরীক্ষায় ব্যর্থ হয়েছে এবং গত বছরের জুলাই থেকে আপডেট হয়নি।
ডেভিডএস

1
5 দিন আগে এটির উপর আপডেট হয়েছিল এবং টানার অনুরোধটি একত্রিত করা হয়েছিল।
এপিকপান্ডাফোরস

6
কমন্স ল্যাং ৩.৩ প্রকাশিত হয়েছিল বেশ কয়েকদিন আগে। আমি নিশ্চিত করেছি যে এটি এখন চলছে। এটি on এ কাজ করে না Ø উইকির নিবন্ধটি Ø এর জন্য পড়া , আমি নিশ্চিত নই যে এটি "ও" দিয়ে প্রতিস্থাপন করা উচিত: এটি নরওয়েজিয়ান এবং ডেনিশ ভাষায় একটি পৃথক চিঠি , "জেড" এর পরে বর্ণমালা হয়েছে। এটি "স্ট্রিপ অ্যাকসেন্টস" পদ্ধতির সীমাবদ্ধতার একটি ভাল উদাহরণ।
ডেভিডএস

2
আপনি যদি গ্রন্থাগারটি অন্তর্ভুক্ত না করতে চান তবে আপনি কমন্স.এপাচি.আর.গ্রাফিক
কমন্স

2
ডেন হিসাবে, ডেনিশ / নরওয়েজিয়ান-যেমন ফরাসি œ এবং জার্মান / সুইডিশ / হাঙ্গেরিয়ান / এস্তোনীয় ইত্যাদি ö লেখার সংক্ষিপ্ত পথ হিসাবে উদ্ভূত। সুতরাং আপনার উদ্দেশ্য উপর নির্ভর করে এটি আপনি চান বিকল্প হতে পারে।
ওলে ভিভি

57

@ ভার্গো 47 দ্বারা সমাধানটি খুব দ্রুত তবে আনুমানিক। গৃহীত উত্তরটি নরমালাইজার এবং একটি নিয়মিত অভিব্যক্তি ব্যবহার করে। আমি ভাবলাম যে নিয়মিত প্রকাশের তুলনায় নরমালাইজার সময়টির কোন অংশটি নিয়েছিল, যেহেতু সমস্ত নন-এএসসিআইআই অক্ষরগুলি সরানো কোনও রেজেক্স ছাড়াই করা যেতে পারে:

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);
}

এই প্রকরণটির নরমালাইজার ব্যবহার করা একের যথার্থতা এবং একটি টেবিল ব্যবহারের সাথে কিছু গতির সুবিধা রয়েছে। আমার মেশিনে, এটি গৃহীত উত্তরের চেয়ে প্রায় 4x গতিযুক্ত, এবং 6 ভার্সন থেকে 7x ধীর যে @ ভার্জ 47৪ এর (স্বীকৃত উত্তরটি আমার মেশিনে @ ভার্জ 4747 এর চেয়ে ২xx ধীর)।


2
outবৈধ অক্ষরের সংখ্যাটি jস্ট্রিং অবজেক্ট তৈরির আগে ব্যবহার করতে গিয়ে তাকে অবশ্যই পুনরায় আকার দিতে হবে।
লেফটারিস ই

4
এই সমাধানে আমার আপত্তি আছে। "Æøåá" ইনপুটটি কল্পনা করুন। বর্তমান flattenToAsciiফলাফল "আ .." তৈরি করে যেখানে বিন্দুগুলি \ u0000 উপস্থাপন করে। এটা ভাল না। প্রথম প্রশ্নটি হল - "অস্বাভাবিক" অক্ষরগুলি কীভাবে উপস্থাপন করবেন? আসুন বলি এটি হবে?, বা আমরা সেখানে NULL চর ছেড়ে যেতে পারি, তবে যে কোনও ক্ষেত্রে আমাদের এগুলির সঠিক অবস্থানটি সংরক্ষণ করতে হবে (ঠিক যেমন রেজেক্স সলিউশন করে)। এর জন্য যদি লুপের মধ্যে অবশ্যই এমন কিছু হওয়া উচিত: if (c <= '\u007F') out[j++] = c; else if (Character.isLetter(c)) out[j++] = '?';এটি এটি কিছুটা কমিয়ে দেবে, তবে এটি অবশ্যই প্রথমে সঠিক হওয়া উচিত। ;-)
কুমারী 47

আমার শেষ মন্তব্যটি বিজ্ঞাপন করুন (তারা খুব বেশি দীর্ঘ হতে পারে না) - ইতিবাচক গ্রহণ ( isLetter) সঠিক নয়, তবে আমি এর চেয়ে ভাল খুঁজে পাইনি। আমি ইউনিকোড বিশেষজ্ঞ নই, তাই মূল চরিত্রের পরিবর্তে একক চরিত্রের শ্রেণিটি কীভাবে আরও ভালভাবে চিহ্নিত করা যায় তা আমি জানি না। বেশিরভাগ অ্যাপ্লিকেশন / ব্যবহারের জন্য চিঠিগুলি ঠিক আছে।
কুমারী 47

1
আপনি সম্ভবত এনএফডি-র পরিবর্তে নরমালাইজার.ফর্ম.এনএফকেডি ব্যবহার করতে চান - এনএফকেডি লিগ্যাচারের মতো জিনিসকে এসকিআই অক্ষরে রূপান্তরিত করবে (উদাহরণস্বরূপ fi ফাইতে), এনএফডি এটি করবে না।
চেস্টার্ম 8

2
আমাদের জন্য আমরা চরিত্রটি পুরোপুরি মুছে ফেলতে চেয়েছিলাম। সেখানে নাল অক্ষরগুলি অনুসরণ না করে তা নিশ্চিত করতে আমি তাদের বিকল্প স্ট্রিং কনস্ট্রাক্টর দিয়ে সরিয়েছি: নতুন স্ট্রিং ফিরিয়ে দিন (আউট, 0, জে);
মাইক সমারাস

30

সম্পাদনা: আপনি যদি জাভা <6 এর সাথে আটকে না থাকেন এবং গতি সমালোচনা না করে এবং / অথবা অনুবাদ টেবিলটি খুব সীমাবদ্ধ থাকে তবে ডেভিডের উত্তরটি ব্যবহার করুন। পয়েন্টটি Normalizerলুপের ভিতরে অনুবাদ টেবিলের পরিবর্তে (জাভা 6 তে প্রবর্তিত) ব্যবহার করা হয়।

যদিও এটি "নিখুঁত" সমাধান নয়, আপনি যখন পরিসীমাটি জানেন (এটি আমাদের ক্ষেত্রে ল্যাটিন ১,২), জাভা before এর আগে কাজ করেছেন (যদিও আসল সমস্যা নয়) এবং সর্বাধিক প্রস্তাবিত সংস্করণটির তুলনায় অনেক দ্রুত (সম্ভবত বা হতে পারে) কোনও সমস্যা হবে না):

    /**
 * 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);
}

আমার এইচডাব্লুতে 32 বিবিডি জেডিকে দিয়ে পরীক্ষাগুলি দেখায় যে এটি àèéľšťč89FDČ থেকে aeelstc89FDC তে রূপান্তর সম্পাদন করে 100 মিলিয়ন ডলারে যখন নর্মালাইজার wayষধটি 3.7s (37x ধীর) হয়। আপনার প্রয়োজনীয়তা যদি পারফরম্যান্সের কাছাকাছি হয় এবং আপনি ইনপুট পরিসরটি জানেন তবে এটি আপনার পক্ষে হতে পারে।

উপভোগ করুন :-)


1
প্রস্তাবিত সংস্করণটির অনেকটা অলসতা নিয়মিত অভিব্যক্তির কারণে, নরমালাইজারের কারণে নয়। নরমালাইজার ব্যবহার করে তবে 'হাতের' দ্বারা নন-এএসসিআইআই অক্ষরগুলি সরিয়ে ফেলা দ্রুততর, যদিও এখনও আপনার সংস্করণটির চেয়ে তত দ্রুত নয়। তবে এটি কেবল লাতিন 1 এবং ল্যাটিন 2 এর পরিবর্তে সমস্ত ইউনিকোডের জন্য কাজ করে।
ডেভিড কনরাড

আমি এটি আরও অক্ষর, পেস্টবিন .com/ এফএএএম 6 এ 2 জে নিয়ে কাজ করতে প্রসারিত করেছি , দ্রষ্টব্য যে এটি মাল্টিচর অক্ষর যেমন DŽ (ডিজেড) এর সাথে সঠিকভাবে কাজ করবে না। এটি এ থেকে কেবলমাত্র 1 টি চরিত্র তৈরি করবে। এছাড়াও আমার ফাংশন স্ট্রিংগুলির পরিবর্তে চর ব্যবহার করে, এটি যদি দ্রুত আপনি যদি যেভাবেই চর পরিচালনা করছেন তবে আপনাকে রূপান্তর করতে হবে না।
জেমস টি

আরে আমি বুঝতে পারছি না tab00c0 ফিল্ডের সেই অক্ষরগুলি কী? উদাহরণস্বরূপ "এএএএএএএসিইইইআইআইআইআই" বা "lLlNnNnNnnNnOoOo" ইত্যাদি এগুলি আগে কখনও দেখেনি। আপনি তাদের কোথায় পেলেন? এছাড়াও আপনি কেবল কোরস্পন্ডিং কোডগুলি ব্যবহার করেন না কেন?
থানোস ফিশারম্যান

@ থানোসএফ কেবল কোডটি দিয়ে যাওয়ার চেষ্টা করুন (প্রয়োজনে ডিবাগার সহ)। এটি স্ট্রিংয়ের প্রতিটি চরিত্রের জন্য যা করে: "এই চরিত্রটি কি \ u00c0 এবং \ u017f এর মধ্যে? যদি তা হয় তবে এটি টেবিল থেকে 7 বিট ASCII অক্ষর দ্বারা প্রতিস্থাপন করুন।" সারণীতে কেবলমাত্র দুটি এনকোডিং পৃষ্ঠা (ল্যাটিন 1 এবং 2) তাদের 7 বিটের সমতুল্য সহ কভার করা হয়েছে। সুতরাং কোডটির অক্ষর যদি \ u00e0 (with) হয় তবে এটি সারণির 32 তম অবস্থান (e0-c0 = 32) থেকে এটির 7 বিট প্রায় গ্রহণ করবে - এটি "একটি" a কিছু অক্ষর অক্ষর নয়, সেগুলি তাদের কোড সহ সেখানে রেখে দেওয়া হয়।
কুমারী 47

তোমার ব্যাখ্যার জন্য ধন্যবাদ. আমি এই এনকোডিং পৃষ্ঠাগুলি কোথায় পেতে পারি যাতে আমি এই ভেরিয়েবলটি আমার ভাষায় প্রসারিত করতে পারি? (গ্রীক) স্বীকৃত উত্তরটি ইতিমধ্যে গ্রীক স্বীকৃত চিঠিগুলির পরিবর্তে কাজটি করেছে তবে আমি আপনার পদ্ধতিটিও চেষ্টা করে কিছুটা
বেনমার্ক

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 ঠিক ঠিক কাজ করে তবে লিনাক্সে (64 বি) জে রকিট (1.6.0_29 64 বি) দিয়ে আমি এই সমস্যার মুখোমুখি হয়েছি। এটি অন্য কোনও সেটআপের মাধ্যমে নিশ্চিত করতে পারছি না, সেই মূলসূত্রটি নিশ্চিত করতে পারে না, তবে আমি নিশ্চিত করতে পারি যে অন্যান্য প্রস্তাবিত সমাধান কাজ করেছে এবং তার জন্য আমি এটিকে ভোট দিয়েছি। :-) (বিটিডাব্লু: এটি কিছু প্রতিস্থাপন করেছিল, তবে যথেষ্ট নয়, এটি উদাহরণস্বরূপ U ইউতে পরিবর্তিত হয়েছিল, তবে á এ-তে নয়))
কুমারী 4747

1
আপনি সম্ভবত এনএফডি-র পরিবর্তে নরমালাইজার.ফর্ম.এনএফকেডি ব্যবহার করতে চান - এনএফকেডি লিগ্যাচারের মতো জিনিসকে এসকিআই অক্ষরে রূপান্তরিত করবে (উদাহরণস্বরূপ fi ফাইতে), এনএফডি এটি করবে না।
চেস্টার্ম 8

@KarolS আমি তাদের দেখতে না পান কোন ধারণকারী কথা
Eis

@ ইয়েস একটি চিঠি জুড়ে একটি স্ল্যাশ একটি ডায়াক্রিটিক হিসাবে গণনা করা হয়েছে: en.wikedia.org/wiki/Diacritic এবং আপনি যদি সেই উইকিপিডিয়া পৃষ্ঠায় যেমন "উচ্চারণ" এর কঠোর সংজ্ঞা অনুসরণ করেন, তবে ডায়ারেসিস একটি উচ্চারণ নয়, সুতরাং নিকো এর উত্তর এখনও ভুল।
করোল এস

6

ভাষার উপর নির্ভর করে, সেগুলি উচ্চারণ হিসাবে বিবেচনা করা যাবে না (যা বর্ণের শব্দ পরিবর্তন করে), তবে বর্ণনামূলক চিহ্নগুলি

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

"বসনিয়ান এবং ক্রোয়েশিয়ান ভাষায় č, ć, đ, š এবং the চিহ্ন রয়েছে, যা পৃথক বর্ণ হিসাবে বিবেচিত হয় এবং অভিধান এবং অন্যান্য প্রসঙ্গে যেমন তালিকাভুক্ত হয় যেখানে বর্ণমালা অনুসারে শব্দগুলি তালিকাভুক্ত করা হয়।"

এগুলি সরিয়ে ফেলা হতে পারে অন্তর্নিহিতভাবে শব্দের অর্থ পরিবর্তন করা, বা বর্ণগুলি সম্পূর্ণ আলাদা করে দেওয়া।


5
একমত। উদাহরণস্বরূপ সুইডিশ ভাষায়: "হেরা" (শুনুন) -> "হোরা" (বেশ্যা)
ক্রিস্টোফার হামারস্ট্রিম

14
তাদের অর্থ কী তা বিবেচ্য নয়। এগুলি কীভাবে সরিয়ে ফেলা হবে তা প্রশ্ন।
এরিক রবার্টসন

7
এরিক: তাদের কী বলা হয় তা বিবেচ্য। যদি প্রশ্নটি কীভাবে অ্যাকসেন্টগুলি সরিয়ে ফেলতে হয় এবং যদি সেগুলি উচ্চারণ না হয় তবে উত্তরটি কেবল উচ্চারণের মতো দেখতে সমস্ত জিনিস কীভাবে সরিয়ে ফেলা যায় তা নাও হতে পারে। যদিও এটি সম্ভবত একটি মন্তব্য নয় এবং উত্তর নয়।
স্মাগ 16

4
আমি মনে করি এর সাধারণ ব্যবহারের ক্ষেত্রে অনুসন্ধান, বিশেষত মিশ্র ভাষার সন্ধান, প্রায়শই একটি ইংরাজী কীবোর্ডের সাথে ইনপুট হিসাবে থাকে, সেক্ষেত্রে মিথ্যা negativeণাত্মক চেয়ে মিথ্যা ধনাত্মক হওয়া ভাল।
নীলস্কেপ

3

আমি স্ট্রিংস সমতা পরীক্ষার সাথে সম্পর্কিত একই সমস্যার মুখোমুখি হয়েছি, তুলনা করার স্ট্রিংগুলির একটিতে ASCII অক্ষর কোড 128-255 রয়েছে

যেমন, অ-ব্রেকিং স্পেস - [হেক্স - এ0] স্পেস [হেক্স - 20]। এইচটিএমএলের মাধ্যমে নন-ব্রেকিং স্পেস দেখাতে। আমি নিম্নলিখিত ব্যবহার করেছি 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()));

বাইটস আউটপুট:

এস 1: [77, 121, 3283, 97, 109, 112, 108, 101 32, 83, 112, 97, 99, 101 32,, 68, 97, 116, 97] এস 2: [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();
}
  • Java জাভার জন্য ইউনিকোড স্ট্রিংয়ের এএসসিআইআই লিখিত লিপি। unidecode

    String initials = Unidecode.decode( s2 );
  • ➩ ব্যবহার Guava: গুগল কোর Libraries for Java

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

    স্পেসের জন্য ইউআরএল এনকোডের জন্য পেয়ারা লাইব্রেরি ব্যবহার করুন।

    String encodedString = UrlEscapers.urlFragmentEscaper().escape(inputString);
  • Some কারওর 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);

স্ট্রিং এবং আউটপুটগুলির বিভিন্ন পদ্ধতির যেমন ➩ ইউনিিডকোড, নরমালাইজার, স্ট্রিংআপসগুলি পরীক্ষা করে

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 );

Unidecode ব্যবহার করে 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

আমি জুনিডিকোডের পরামর্শ দিই । এটি কেবল 'Ł' এবং 'Ø' পরিচালনা করবে না, তবে এটি অন্যান্য বর্ণমালা, যেমন চীনা, থেকে লাতিন বর্ণমালায় প্রতিলিপি করার জন্যও ভাল কাজ করে।


1
প্রতিশ্রুতিবদ্ধ মনে হচ্ছে, তবে আমি আশা করি এটি একটি আরও সক্রিয় / রক্ষণাবেক্ষণ প্রকল্প এবং মাভেনের জন্য উপলব্ধ।
ফিল

2

@ ডেভিড কনরাড সমাধানটি আমি নরমালাইজারটি ব্যবহার করার দ্রুত চেষ্টা করেছি তবে এতে একটি বাগ রয়েছে। এটি মূলত অক্ষরগুলিকে স্ট্রিপগুলি দেয় যা অ্যাকসেন্ট নয়, উদাহরণস্বরূপ চীনা অক্ষর এবং other এর মতো অন্যান্য অক্ষরগুলি সমস্ত ছাঁটাই হয়। আমরা যে অক্ষরগুলি ফেলাতে চাই তা হ'ল ফাঁক চিহ্ন, অক্ষরগুলি যা চূড়ান্ত স্ট্রিংয়ে অতিরিক্ত প্রস্থ নেয় না। এই শূন্য প্রস্থের অক্ষরগুলি মূলত অন্য কোনও অক্ষরে মিলিত হয়। আপনি যদি এগুলিকে একটি চরিত্র হিসাবে বিচ্ছিন্ন দেখতে পান, উদাহরণস্বরূপ এই `এর মতো, আমার ধারণা এটি স্থানের অক্ষরের সাথে একত্রিত।

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

আপনার কোনও লাইব্রেরি না থাকলে রেজেক্স এবং নরমালাইজার ব্যবহারের অন্যতম সেরা উপায় হ'ল:

    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

উদাহরণস্বরূপ, কম্পোজিট ইউনিকোড দ্বারা রচিত "Ồ" প্রিকম্পোজড ইউনিকোড দ্বারা লিখিত "Ồ" থেকে পৃথক। আপনি আমার নমুনা অক্ষর অনুলিপি করতে পারেন এবং পার্থক্যটি দেখতে তাদের রূপান্তর করতে পারেন।

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

আমি কিছু ব্যাঙ্কের জন্য তথ্যটি কোর-ব্যাঙ্কে প্রেরণের আগে (সাধারণত ইউনিকোড সমর্থন করে না) রূপান্তর করার জন্য এই বৈশিষ্ট্যটি তৈরি করেছি এবং শেষ ব্যবহারকারীরা ডেটা ইনপুট করার জন্য একাধিক ইউনিকোড টাইপিং ব্যবহার করার সময় এই সমস্যার মুখোমুখি হয়েছিল। সুতরাং আমি মনে করি, এইচএক্সে রূপান্তর করা এবং এটি প্রতিস্থাপন করা সবচেয়ে নির্ভরযোগ্য উপায়।


-1

যদি কেউ কোটলিনে এটি করার জন্য লড়াই করছে, এই কোডটি কবজির মতো কাজ করে। অসঙ্গতি এড়াতে আমি। টুঅপারকেস এবং ট্রিম () ব্যবহার করি। তারপরে আমি এই ফাংশনটি ফেলেছি:

   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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.