如何将Unicode编码的string转换为string
我有一个Unicode编码的string\uXXXX
,我想把它转换成一个普通的字母( UTF-8 )。 例如:
String myString = "\u0048\u0065\u006C\u006C\u006F World";
应该成为
"Hello World"
我知道,当我打印string,它显示Hello world
。 我的问题是我从Unix机器上的文件读取文件名,然后我search它们。 文件名是用Unicode编码的,当我search这些文件时,我找不到它们,因为它search的文件名是\uXXXX
。
在技术上做:
String myString = "\u0048\u0065\u006C\u006C\u006F World";
自动将其转换为"Hello World"
,所以我假设你正在从一些文件中读取string。 为了将其转换为“Hello”,您必须将文本parsing为单独的Unicode数字(带上\uXXXX
并获得XXXX
),然后执行Integer.ParseInt(XXXX, 16)
以获得hex值,然后情况下,以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
Apache Commons Lang 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
您可能需要使用Apache Commons Lang的StringEscapeUtils
,即:
String unicode = "\u0048\u0065\u006C\u006C\u006F"; String Title = StringEscapeUtils.unescapeJava(unicode);
这个简单的方法在大多数情况下都能正常工作,但是会跳到“u005Cu005C”这样的string上,解码为“\ u0048”,但是实际上会解码“H”,因为第一遍会产生“\ u0048”作为工作string然后通过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; }
字节编码和string
在java中用于转换string(String)中的字节stream(byte [])并返回到String类的特性如下:
构造函数String (byte [] bytes, String enc)
接收input的字节stream与他们的编码; 如果编码被省略,它将被默认接受
getBytes Method (String enc)
返回以指定编码logging的字节stream; 编码也可以省略。
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(); }
从你的问题来看,这并不完全清楚,但是我假设你说你有一个文件,每行文件都是文件名。 每个文件名都是这样的:
\u0048\u0065\u006C\u006C\u006F
换句话说,文件名文件中的字符是\
, u
, 0
等等。
如果是这样,你所看到的是预期的。 Java只能在源代码中的string文本中转换\uXXXX
序列(以及在存储的Properties
对象中读取时)。 当你读取你的文件内容时,你将会得到一个由字符\
, u
,0,0,4,8等组成的string,而不是stringHello
。
因此,您需要parsing该string以提取0065
等部分,然后将其转换为char
并从这些string中创build一个string,然后将该string传递给打开该文件的例程。
尝试
private static final Charset UTF_8 = Charset.forName("UTF-8"); private String forceUtf8Coding(String input) {return new String(input.getBytes(UTF_8), UTF_8))}
更短的版本:
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; }
一个简单的方法我知道使用JsonObject:
try { JSONObject json = new JSONObject(); json.put("string", myString); String converted = json.getString("string"); } catch (JSONException e) { e.printStackTrace(); }
实际上,我写了一个包含一些实用程序的开源库。 其中之一是将Unicode序列转换为string,反之亦然。 我发现它非常有用。 这里是关于这个关于Unicode转换器的文章的引用:
类StringUnicodeEncoderDecoder具有可以将string(以任何语言)转换为Unicode字符序列的方法,反之亦然。 例如一个string“Hello World”将被转换成
“\ u0048 \ u006c \ u006c \ u006f \ u0057 \ u006f \ u0072 \ u006c \ u0064”
并可能恢复。
这里是整个文章的链接,解释图书馆有哪些实用工具,以及如何让图书馆使用它。 它可以作为Maven工件或作为来自Github的源。 这是非常容易使用。 带有堆栈跟踪过滤的开源Java库,静音stringparsingUnicode转换器和版本比较
这是我的解决scheme…
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; } };