2012-06-21 324 views
42

我有一個字符串,Unicode編碼\uXXXX,我想將其轉換爲常規字母(UTF-8)。例如:如何將Unicode編碼的字符串轉換爲字符串

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

應該成爲

"Hello World" 

我知道,當我打印字符串它顯示Hello world。我的問題是我從Unix機器上的文件讀取文件名,然後搜索它們。文件名使用Unicode編碼,當我搜索這些文件時,我找不到它們,因爲它搜索名稱中包含\uXXXX的文件。

+0

你確定?你不認爲這些字符只是簡單地打印成Unicode轉義符? –

+3

'\ u0048' *是*'H' - 它們是一樣的。 Java中的字符串採用Unicode。 –

+0

我想這個問題可能與我的Java到UNIX API - 字符串我得到的是類似的東西\ u3123 \ u3255_file_name.txt。而Java不會隱藏它。 – SharonBL

回答

23

技術上做:

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

自動將其轉換爲"Hello World",所以我假定你是從一些文件中的字符串在讀。爲了將其轉換爲「Hello」,您必須將文本解析爲單獨的Unicode數字(以\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 
+0

似乎可能是解決方案。你有一個想法,我怎麼能在java中做到 - 我可以用String.replaceAll或類似的東西嗎? – SharonBL

+0

@SharonBL我更新了一些代碼,至少應該讓你知道從哪裏開始。 – NominSim

+2

非常感謝您的幫助!我還發現了另一個解決方案:String s = StringEscapeUtils.unescapeJava(「\\ u20ac \\ n」);它做的工作! – SharonBL

4

從你的問題中不完全清楚,但我假設你說你有一個文件,該文件的每一行是一個文件名。並且每個文件名是這樣的:

\u0048\u0065\u006C\u006C\u006F 

換句話說,文件名的文件中的字符是\u0048等。

如果是這樣,你所看到的是預期的。 Java僅在源代碼中以字符串文字翻譯\uXXXX序列(並且在讀取存儲的Properties對象時)。當你閱讀的內容,你的文件,你將有包括人物\u0048等和字符串Hello的字符串。

所以,你需要解析該字符串提取00480065等片,然後將其轉換爲char S和那些char作一個字符串,然後將字符串傳遞給打開該文件的程序。

60

Apache Commons LangStringEscapeUtils.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 
+0

字符串sJava = 「\ u0048 \\ u0065 \ u006C \ u006C \ u006F」; ----->請做簡單的改變。 –

13

您可能需要使用StringEscapeUtilsApache Commons Lang,即:

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

+2

添加在的build.gradle dependacy後:編譯「公地郎鹹平:公地郎鹹平:2.6」 上述工作的罰款。 –

7

這個簡單的方法在大多數情況下工作,但會絆倒過類似「u005Cu005C」這應該解碼字符串「\ u0048」,但實際上解碼「H」爲先pass產生「\ u0048」作爲工作字符串,然後再由while循環處理。

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; 
} 
+0

試圖重塑標準Java庫提供的方法。只需檢查純粹的實現https://stackoverflow.com/a/39265921/1511077 –

3

嘗試

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

較短的版本:

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; 
} 
+0

試圖重新創建標準Java庫提供的方法。只是檢查純粹的實現https://stackoverflow.com/a/39265921/1511077 –

1

一個簡單的方法,我知道使用的JSONObject:

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

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

Byte Encodings and Strings

在java中在字符串(string)的字節流(字節[])的轉化率和回String類具有以下特點:

構造String (byte [] bytes, String enc)接收與它們的編碼的字節的輸入流;如果省略編碼,則默認接受

getBytes Method (String enc)返回以指定編碼記錄的字節流;編碼也可以省略。

try { 
    String myString = "\u0048\u0065\u006C\u006C\u006F World"; 
    byte[] utf8Bytes = myString.getBytes("UTF8"); 
    String text = new String(utf8Bytes,"UTF8"); 
} 
catch (UnsupportedEncodingException e) { 
    e.printStackTrace(); 
} 
+1

這個答案使用由'java.lang.String'提供的方法,它的專業性。 – Eddy

0

其實,我寫了一個包含一些實用程序的開源庫。其中之一是將Unicode序列轉換爲字符串,反之亦然。我發現它非常有用。下面是關於該庫的有關Unicode轉換文章報價:

類StringUnicodeEncoderDecoder具有可轉換 字符串(在任何語言)爲Unicode字符和 反之亦然序列的方法。例如,一個字符串 「Hello World」 將被轉換成

「\ u0048 \ u0065 \ u006c \ u006c \ u006f \ u0020 \ u0057 \ u006f \ u0072 \ u006c \ u0064」

,並可以恢復回來。

下面是整篇文章的鏈接,它解釋了庫的實用工具以及如何讓庫使用它。它可以作爲Maven工件使用,也可以作爲Github的源代碼使用。這是非常容易使用。 Open Source Java library with stack trace filtering, Silent String parsing Unicode converter and Version comparison

0

這裏是我的解決方案...

   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; 
        } 
       }; 
+0

試圖重塑標準Java庫提供的標準方法。只需檢查純實施https://stackoverflow.com/a/39265921/1511077 –

-1
public static String getEnglishText(String textWithUnicode){ 
     String word=""; 
     String newText= textWithUnicode; 
     int position=newText.indexOf("\\u"); 
     while(position!=-1) { 
     if(position!=0){ 
      word+=newText.substring(0,position); 
     } 
     String token=newText.substring(position+2,position+5); 
     newText=newText.substring(position+5); 
     word+=(char)Integer.parseInt(token); 
     position=newText.indexOf("\\u");} 
     word+=newText; 
     return word; 
    } 

這個工作對me.Check這個!

0

解決方案科特林:

val result = String(someText.toByteArray()) 

科特林使用UTF-8處處爲默認編碼

您也可以實現它作爲擴展String類:

fun String.unescape(): String { 
    return String(this.toByteArray()) 
} 

,然後使用簡單:

val result = someText.unescape() 

;)

相關問題