यूनिकोड एन्कोडिंग के साथ स्ट्रिंग को अक्षरों की एक स्ट्रिंग में कैसे परिवर्तित किया जाए


84

मेरे पास बच गए यूनिकोड पात्रों के साथ एक स्ट्रिंग है \uXXXX, और मैं इसे नियमित यूनिकोड अक्षरों में बदलना चाहता हूं। उदाहरण के लिए:

"\u0048\u0065\u006C\u006C\u006F World"

बन जाना चाहिए

"Hello World"

मुझे पता है कि जब मैं पहले स्ट्रिंग को प्रिंट करता हूं तो यह पहले से ही दिखाता है Hello world। मेरी समस्या यह है कि मैं एक फ़ाइल से फ़ाइल नाम पढ़ता हूं, और फिर मैं उनके लिए खोज करता हूं। फ़ाइल में फ़ाइल नाम यूनिकोड एन्कोडिंग के साथ बच गए हैं, और जब मैं फ़ाइलों की खोज करता हूं, तो मैं उन्हें नहीं ढूंढ सकता, क्योंकि यह \uXXXXअपने नाम के साथ एक फ़ाइल की खोज करता है ।


आप को यकीन है? आप यह नहीं मानते कि यूनिकोड के बचते ही पात्र मुद्रित हो रहे हैं?
हॉट लिक्स

5
\u0048 है H - वे एक और एक ही हैं। जावा में स्ट्रिंग्स यूनिकोड में हैं।
हॉट लिक्स

मुझे लगता है कि समस्या मेरे जावा के साथ यूनिक्स एपीआई के लिए हो सकती है - मुझे जो स्ट्रिंग मिलती है वह \ u3123 \ u3255_file_name.txt की तरह है। और जावा इसे कवर नहीं करता है।
शेरोनबीएल

3
UTF-8 है एक यूनिकोड एन्कोडिंग।
पावेल रेड्ज़विलोव्स्की

5
यह आपके प्रश्न का उत्तर नहीं है, लेकिन मुझे यूनिकोड और यूटीएफ -8 के बीच के अंतर को स्पष्ट करने दें, जो कि बहुत से लोगों को चुभने लगते हैं। यूनिकोड एक विशेष है एक-से-एक वर्णों के बीच मानचित्रण के रूप में हम उन्हें पता है ( a, b, $, £पूर्णांकों के लिए, आदि)। उदाहरण के लिए, प्रतीक Aको 65 नंबर दिया गया है, और \n10. इसका इससे कोई लेना- देना नहीं है कि तार या वर्णों को डिस्क पर या किसी पाठ फ़ाइल में कैसे दर्शाया गया है। UTF-8 एक विनिर्देशन (यानी एन्कोडिंग) है कि कैसे इन पूर्णांकों (यानी प्रतीकों) को बाइट्स (बिट स्ट्रिंग्स) के रूप में दर्शाया जाता है, ताकि वे बेबाकी से लिखे और एक फ़ाइल से पढ़ सकें।
डस्टबाइट

जवाबों:


49

तकनीकी रूप से कर रहे हैं:

String myString = "\u0048\u0065\u006C\u006C\u006F World";

स्वचालित रूप से इसे में कनवर्ट करता है "Hello World", इसलिए मुझे लगता है कि आप कुछ फ़ाइल से स्ट्रिंग में पढ़ रहे हैं। इसे "हैलो" में बदलने के लिए, आपको पाठ को अलग-अलग यूनिकोड अंकों में पार्स करना होगा, (ले \uXXXXऔर बस प्राप्त करें XXXX) फिर Integer.ParseInt(XXXX, 16)एक हेक्स मान प्राप्त करने के लिए करें और फिर charवास्तविक चरित्र प्राप्त करने के लिए मामला करें ।

संपादित करें: इसे पूरा करने के लिए कुछ कोड:

String str = myString.split(" ")[0];
str = str.replace("\\","");
String[] arr = str.split("u");
String text = "";
for(int i = 1; i < arr.length; i++){
    int hexVal = Integer.parseInt(arr[i], 16);
    text += (char)hexVal;
}
// Text will now have Hello

लगता है कि समाधान हो सकता है। क्या आपके पास एक विचार है कि मैं इसे जावा में कैसे कर सकता हूं - क्या मैं इसे String.replaceAll या कुछ और के साथ कर सकता हूं?
शेरोनबेल

@SharonBL I ने कुछ कोड के साथ अपडेट किया, कम से कम आपको यह विचार करना चाहिए कि कहां से शुरू करना है।
नोमिनसिम

2
आपकी मदद के लिए बहुत बहुत धन्यवाद! मुझे इसके लिए एक और समाधान भी मिला: स्ट्रिंग s = StringEscapeUtils.unescapeJava ("\\ u20ac \\ n"); यह काम करता है!
शेरोनबीएल

2
मानक जावा लाइब्रेरी द्वारा प्रदान किए गए तरीकों को फिर से बनाने का प्रयास। बस शुद्ध कार्यान्वयन stackoverflow.com/a/39265921/1511077 की
एवगेनी Lebedev

1
मैं हमेशा चकित रह जाता हूं जब एक " पहिया को सुदृढ़ करता है " जवाब को इतने सारे वोट मिलते हैं।
पेड्रो लोबिटो

93

अपाचे कॉमन्स लैंग StringEscapeUtils.unescapeJava () यह ठीक से डिकोड कर सकते हैं।

import org.apache.commons.lang.StringEscapeUtils;

@Test
public void testUnescapeJava() {
    String sJava="\\u0048\\u0065\\u006C\\u006C\\u006F";
    System.out.println("StringEscapeUtils.unescapeJava(sJava):\n" + StringEscapeUtils.unescapeJava(sJava));
}


 output:
 StringEscapeUtils.unescapeJava(sJava):
 Hello

स्ट्रिंग sJava = "\ u0048 \\ u0065 \ u006C \ u006C \ u006F"; -----> कृपया सरल परिवर्तन करें।
श्रेयांश शाह

30

आप अपाचे कॉमन्स लैंगStringEscapeUtils से उपयोग कर सकते हैं , अर्थात:

String Title = StringEscapeUtils.unescapeJava("\\u0048\\u0065\\u006C\\u006C\\u006F");


5
build.gradle में निर्भरता जोड़ने के बाद: ठीक काम करने के ऊपर 'commons-lang: commons-lang: 2.6' संकलित करें।
जोसेफ मेकवान

8

यह सरल विधि अधिकांश मामलों के लिए काम करेगी, लेकिन "u005Cu005C" जैसी किसी चीज पर यात्रा करेगी, जिसे स्ट्रिंग "\ u0048" को डिकोड करना चाहिए, लेकिन वास्तव में "H" को डिकोड करना होगा क्योंकि पहला पास वर्किंग स्ट्रिंग के रूप में "\ u0048" का उत्पादन करता है। तब फिर से लूप द्वारा संसाधित किया जाता है।

static final String decode(final String in)
{
    String working = in;
    int index;
    index = working.indexOf("\\u");
    while(index > -1)
    {
        int length = working.length();
        if(index > (length-6))break;
        int numStart = index + 2;
        int numFinish = numStart + 4;
        String substring = working.substring(numStart, numFinish);
        int number = Integer.parseInt(substring,16);
        String stringStart = working.substring(0, index);
        String stringEnd   = working.substring(numFinish);
        working = stringStart + ((char)number) + stringEnd;
        index = working.indexOf("\\u");
    }
    return working;
}

मानक जावा लाइब्रेरी द्वारा प्रदान किए गए तरीकों को फिर से बनाने का प्रयास। बस शुद्ध कार्यान्वयन stackoverflow.com/a/39265921/1511077 की
एवगेनी Lebedev

1
धन्यवाद @EvgenyLebedev ... मानक पुस्तकालय का तरीका अच्छा लग रहा है और संभवत: पूरी तरह से परीक्षण किया गया है, बहुत सराहना की गई है।
andrew pate

7

छोटा संस्करण:

public static String unescapeJava(String escaped) {
    if(escaped.indexOf("\\u")==-1)
        return escaped;

    String processed="";

    int position=escaped.indexOf("\\u");
    while(position!=-1) {
        if(position!=0)
            processed+=escaped.substring(0,position);
        String token=escaped.substring(position+2,position+6);
        escaped=escaped.substring(position+6);
        processed+=(char)Integer.parseInt(token,16);
        position=escaped.indexOf("\\u");
    }
    processed+=escaped;

    return processed;
}

मानक जावा लाइब्रेरी द्वारा प्रदान किए गए तरीकों को फिर से बनाने का प्रयास। बस शुद्ध कार्यान्वयन stackoverflow.com/a/39265921/1511077 की
इवगेनी लेबेदेव

5

Org.apache.commons.lang3 लाइब्रेरी से StringEscapeUtils को 3.6 के रूप में दर्शाया गया है

तो आप इसके बजाय उनके नए कॉमन्स-टेक्स्ट लाइब्रेरी का उपयोग कर सकते हैं :

compile 'org.apache.commons:commons-text:1.9'

OR

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-text</artifactId>
   <version>1.9</version>
</dependency>

उदाहरण कोड:

org.apache.commons.text.StringEscapeUtils.unescapeJava(escapedString);

4

यह आपके प्रश्न से पूरी तरह से स्पष्ट नहीं है, लेकिन मैं आपको यह कह रहा हूं कि आपके पास एक फ़ाइल है जहां उस फ़ाइल की प्रत्येक पंक्ति एक फ़ाइल नाम है। और प्रत्येक फ़ाइलनाम कुछ इस प्रकार है:

\u0048\u0065\u006C\u006C\u006F

दूसरे शब्दों में, फ़ाइल नाम की फ़ाइल में चरित्र \, u, 0, 0, 4, 8और पर इतना।

यदि हां, तो आप जो देख रहे हैं वह अपेक्षित है। जावा केवल \uXXXXस्रोत कोड में (और संग्रहीत Propertiesवस्तुओं में पढ़ते समय ) स्ट्रिंग स्ट्रिंग में अनुक्रमों का अनुवाद करता है । आप फाइल पात्रों से मिलकर एक स्ट्रिंग होगा आप सामग्री पढ़ने जब \, u, 0, 0, 4, 8और इतने पर और नहीं स्ट्रिंग Hello

तो आपको उस स्ट्रिंग को निकालने के लिए 0048, 0065इत्यादि टुकड़ों को पार्स करना होगा और फिर उन्हें charएस में परिवर्तित करना होगा और उन charएस से एक स्ट्रिंग बनाना होगा और फिर उस स्ट्रिंग को दिनचर्या में शामिल करना होगा जो फ़ाइल को खोलता है।


3

Apache Commons Lang: StringEscapeUtils.unescapeJava () का उपयोग कर सुझाव देने के बारे में अपडेट - यह पदावनत कर दिया गया था,

पदावनत। 3.6 के रूप में, इसके बजाय कॉमन्स-टेक्स्ट StringEscapeUtils का उपयोग करें

प्रतिस्थापन है अपाचे कॉमन्स टेक्स्ट का स्ट्रिंगरस्केप यूटिल्स.यून्सस्केपजवा ()


3

बस रेगेक्स का उपयोग करके, मेरे संस्करण में योगदान करना चाहता था:

private static final String UNICODE_REGEX = "\\\\u([0-9a-f]{4})";
private static final Pattern UNICODE_PATTERN = Pattern.compile(UNICODE_REGEX);
...
String message = "\u0048\u0065\u006C\u006C\u006F World";
Matcher matcher = UNICODE_PATTERN.matcher(message);
StringBuffer decodedMessage = new StringBuffer();
while (matcher.find()) {
  matcher.appendReplacement(
      decodedMessage, String.valueOf((char) Integer.parseInt(matcher.group(1), 16)));
}
matcher.appendTail(decodedMessage);
System.out.println(decodedMessage.toString());

2

मैंने एक प्रदर्शन और त्रुटि-प्रूफ समाधान लिखा:

public static final String decode(final String in) {
    int p1 = in.indexOf("\\u");
    if (p1 < 0)
        return in;
    StringBuilder sb = new StringBuilder();
    while (true) {
        int p2 = p1 + 6;
        if (p2 > in.length()) {
            sb.append(in.subSequence(p1, in.length()));
            break;
        }
        try {
            int c = Integer.parseInt(in.substring(p1 + 2, p1 + 6), 16);
            sb.append((char) c);
            p1 += 6;
        } catch (Exception e) {
            sb.append(in.subSequence(p1, p1 + 2));
            p1 += 2;
        }
        int p0 = in.indexOf("\\u", p1);
        if (p0 < 0) {
            sb.append(in.subSequence(p1, in.length()));
            break;
        } else {
            sb.append(in.subSequence(p1, p0));
            p1 = p0;
        }
    }
    return sb.toString();
}

1

प्रयत्न

private static final Charset UTF_8 = Charset.forName("UTF-8");
private String forceUtf8Coding(String input) {return new String(input.getBytes(UTF_8), UTF_8))}

1

JsonObject का उपयोग करके एक आसान तरीका मुझे पता है:

try {
    JSONObject json = new JSONObject();
    json.put("string", myString);
    String converted = json.getString("string");

} catch (JSONException e) {
    e.printStackTrace();
}

1

यहाँ मेरा समाधान है ...

                String decodedName = JwtJson.substring(startOfName, endOfName);

                StringBuilder builtName = new StringBuilder();

                int i = 0;

                while ( i < decodedName.length() )
                {
                    if ( decodedName.substring(i).startsWith("\\u"))
                    {
                        i=i+2;
                        builtName.append(Character.toChars(Integer.parseInt(decodedName.substring(i,i+4), 16)));
                        i=i+4;
                    }
                    else
                    {
                        builtName.append(decodedName.charAt(i));
                        i = i+1;
                    }
                };

मानक जावा लाइब्रेरी द्वारा प्रदान किए गए मानक तरीकों को फिर से बनाने का प्रयास। बस शुद्ध कार्यान्वयन stackoverflow.com/a/39265921/1511077 की
इवगेनी लेबेदेव

1

तेज

 fun unicodeDecode(unicode: String): String {
        val stringBuffer = StringBuilder()
        var i = 0
        while (i < unicode.length) {
            if (i + 1 < unicode.length)
                if (unicode[i].toString() + unicode[i + 1].toString() == "\\u") {
                    val symbol = unicode.substring(i + 2, i + 6)
                    val c = Integer.parseInt(symbol, 16)
                    stringBuffer.append(c.toChar())
                    i += 5
                } else stringBuffer.append(unicode[i])
            i++
        }
        return stringBuffer.toString()
    }

0

दरअसल, मैंने एक ओपन सोर्स लाइब्रेरी लिखी है जिसमें कुछ यूटिलिटीज हैं। उनमें से एक स्ट्रिंग और विसे-वर्सा को यूनिकोड अनुक्रम परिवर्तित कर रहा है। मैंने इसे बहुत उपयोगी पाया। यहाँ यूनिकोड कनवर्टर के बारे में इस पुस्तकालय के लेख का उद्धरण है:

क्लास StringUnicodeEncoderDecoder में ऐसी विधियाँ हैं जो एक स्ट्रिंग (किसी भी भाषा में) को यूनिकोड वर्णों और दृश्य-छंद के अनुक्रम में परिवर्तित कर सकती हैं। उदाहरण के लिए एक स्ट्रिंग "हैलो वर्ल्ड" में परिवर्तित हो जाएगा

"u0048 \ u0065 \ u006c \ u006c \ u006f \ u0020 \ u0057 \ u006f \ u0072 \ u006c \ u0064"

और वापस बहाल किया जा सकता है।

यहाँ पूरे लेख की लिंक दी गई है जो बताती है कि पुस्तकालय के पास क्या उपयोगिताएँ हैं और इसका उपयोग करने के लिए पुस्तकालय कैसे प्राप्त करें। यह मावेन विरूपण साक्ष्य के रूप में या गितूब से स्रोत के रूप में उपलब्ध है। यह इस्तेमाल में बहुत आसान है। ओपन सोर्स जावा लाइब्रेरी स्टैक ट्रेस फ़िल्टरिंग के साथ, साइलेंट स्ट्रिंग पार्सिंग यूनिकोड कनवर्टर और संस्करण की तुलना


0

जावा 9+ के लिए, आप मिलानकर्ता वर्ग की नई प्रतिस्थापन विधि का उपयोग कर सकते हैं ।

private static final Pattern UNICODE_PATTERN = Pattern.compile("\\\\u([0-9A-Fa-f]{4})");

public static String unescapeUnicode(String unescaped) {
    return UNICODE_PATTERN.matcher(unescaped).replaceAll(r -> String.valueOf((char) Integer.parseInt(r.group(1), 16)));
}

public static void main(String[] args) {
    String originalMessage = "\\u0048\\u0065\\u006C\\u006C\\u006F World";
    String unescapedMessage = unescapeUnicode(originalMessage);
    System.out.println(unescapedMessage);
}

मेरा मानना ​​है कि StringEscapeUtils (एक अतिरिक्त पुस्तकालय का उपयोग नहीं करने के अलावा) द्वारा unescapeJava पर इस दृष्टिकोण का मुख्य लाभ यह है कि आप केवल यूनिकोड वर्ण (यदि आप चाहें) को परिवर्तित कर सकते हैं, क्योंकि बाद वाले सभी बच गए जावा वर्णों (जैसे \ n या \ t) से बचते हैं )। यदि आप सभी बच गए पात्रों को बदलना चाहते हैं तो पुस्तकालय वास्तव में सबसे अच्छा विकल्प है।


0

@ नोमिनसिम में अन्य चरित्र हो सकते हैं, इसलिए मुझे इसकी लंबाई का पता लगाना चाहिए।

private String forceUtf8Coding(String str) {
    str = str.replace("\\","");
    String[] arr = str.split("u");
    StringBuilder text = new StringBuilder();
    for(int i = 1; i < arr.length; i++){
        String a = arr[i];
        String b = "";
        if (arr[i].length() > 4){
            a = arr[i].substring(0, 4);
            b = arr[i].substring(4);
        }
        int hexVal = Integer.parseInt(a, 16);
        text.append((char) hexVal).append(b);
    }
    return text.toString();
}

0

UnicodeUnescaperसे org.apache.commons:commons-textभी स्वीकार्य है।

new UnicodeUnescaper().translate("\u0048\u0065\u006C\u006C\u006F World") रिटर्न "Hello World"


-1

इसे पूरा करने का एक वैकल्पिक तरीका chars()जावा 9 के साथ पेश किया जा सकता है, इसका उपयोग उन वर्णों पर पुनरावृति करने के लिए किया जा सकता है जो यह सुनिश्चित करते हैं कि कोई भी चार्ट जो कि सरोगेट कोड बिंदु पर मैप्स को बिना किसी व्याख्या के पास किया गया है। इसका उपयोग इस प्रकार किया जा सकता है: -

String myString = "\u0048\u0065\u006C\u006C\u006F World";
myString.chars().forEach(a -> System.out.print((char)a));
// would print "Hello World"

-1

मैंने पाया कि कई उत्तरों ने "पूरक वर्ण" के मुद्दे को संबोधित नहीं किया। यहाँ इसका समर्थन करने का सही तरीका है। कोई तृतीय-पक्ष लाइब्रेरी, शुद्ध जावा कार्यान्वयन।

http://www.oracle.com/us/technologies/java/supplementary-142654.html

public static String fromUnicode(String unicode) {
    String str = unicode.replace("\\", "");
    String[] arr = str.split("u");
    StringBuffer text = new StringBuffer();
    for (int i = 1; i < arr.length; i++) {
        int hexVal = Integer.parseInt(arr[i], 16);
        text.append(Character.toChars(hexVal));
    }
    return text.toString();
}

public static String toUnicode(String text) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < text.length(); i++) {
        int codePoint = text.codePointAt(i);
        // Skip over the second char in a surrogate pair
        if (codePoint > 0xffff) {
            i++;
        }
        String hex = Integer.toHexString(codePoint);
        sb.append("\\u");
        for (int j = 0; j < 4 - hex.length(); j++) {
            sb.append("0");
        }
        sb.append(hex);
    }
    return sb.toString();
}

@Test
public void toUnicode() {
    System.out.println(toUnicode("😊"));
    System.out.println(toUnicode("🥰"));
    System.out.println(toUnicode("Hello World"));
}
// output:
// \u1f60a
// \u1f970
// \u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064

@Test
public void fromUnicode() {
    System.out.println(fromUnicode("\\u1f60a"));
    System.out.println(fromUnicode("\\u1f970"));
    System.out.println(fromUnicode("\\u0048\\u0065\\u006c\\u006c\\u006f\\u0020\\u0057\\u006f\\u0072\\u006c\\u0064"));
}
// output:
// 😊
// 🥰
// Hello World

स्ट्रिंग के अंदर गैर यूनिकोड वर्ण होने पर काम नहीं करता है, जैसे: href = \ u0022 \ / en \ / blog \ / d-day-protect-europe-its-demons \ u0022 \ u003E \ n
मोहसिन अबसी

-1

कोटलिन के लिए समाधान:

val sourceContent = File("test.txt").readText(Charset.forName("windows-1251"))
val result = String(sourceContent.toByteArray())

कोटलिन UTF-8 का उपयोग हर जगह डिफ़ॉल्ट एन्कोडिंग के रूप में करता है।

विधि toByteArray()में डिफ़ॉल्ट तर्क है - Charsets.UTF_8


यह सामग्री के वास्तविक उदाहरणों के बिना एक उत्तर नहीं है जो कि सुझावकर्ता के साथ "परिवर्तित" नहीं किया जा सकता है। क्या आप इसे प्रदान कर सकते हैं?
एवगेनी लेबेदेव

String(string.toByteArray())वस्तुतः कुछ भी नहीं प्राप्त होता है।
रस्टीक्स

@rustyx विधि के toByteArray()साथ डिफ़ॉल्ट तर्क है Charsets.UTF_8। फिर आप आवश्यक एन्कोडिंग के साथ बायटियर से एक स्ट्रिंग बनाते हैं। मैं आज windows-1251utf-8 के साथ परीक्षण किया , यह काम करता है। इसके अलावा मैंने बाइट स्तर पर तुलना भी की है :)
एवगेनी लेबेदेव

@rustyx यहाँ आप के लिए एक सार है - gist.github.com/lebe-dev/31e31a3399c7885e298ed86810504676
एव्जेनी लेबेडेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.