2012-06-21 286 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() 

;)

相关问题