给出以下代码:
String tmp = new String("\\u0068\\u0065\\u006c\\u006c\\u006f\\u000a");
String result = convertToEffectiveString(tmp); // result contain now "hello\n"
JDK是否已经为此提供了一些类? 有没有这样做的图书? (最好是在maven下)
我尝试使用ByteArrayOutputStream但没有成功。
答案 0 :(得分:3)
首先,您只是尝试解析字符串文字,还是tmp
将成为用户输入的数据?
如果这将是一个字符串文字(即硬编码字符串),它可以使用Unicode转义编码。在你的情况下,这只是意味着使用单个反斜杠而不是双反斜杠:
String result = "\u0068\u0065\u006c\u006c\u006f\u000a";
但是,如果您需要使用Java的字符串解析规则来解析用户输入,那么一个好的起点可能是Apache Commons Lang的StringEscapeUtils.unescapeJava()方法。
答案 1 :(得分:3)
这样可行,但仅限ASCII。如果你在ASCCI范围之外使用unicode字符,那么你将遇到问题(因为每个字符被填充到一个字节中,而不是UTF-8允许的完整字)。您可以进行下面的类型转换,因为您知道如果您保证输入基本上是ASCII(如您在评论中提到的那样),UTF-8不会溢出一个字节。
package sample;
import java.io.UnsupportedEncodingException;
public class UnicodeSample {
public static final int HEXADECIMAL = 16;
public static void main(String[] args) {
try {
String str = "\\u0068\\u0065\\u006c\\u006c\\u006f\\u000a";
String arr[] = str.replaceAll("\\\\u"," ").trim().split(" ");
byte[] utf8 = new byte[arr.length];
int index=0;
for (String ch : arr) {
utf8[index++] = (byte)Integer.parseInt(ch,HEXADECIMAL);
}
String newStr = new String(utf8, "UTF-8");
System.out.println(newStr);
}
catch (UnsupportedEncodingException e) {
// handle the UTF-8 conversion exception
}
}
}
这是解决仅使用ASCII字符问题的另一种解决方案。这将适用于UTF-8范围内的任何unicode字符,而不是仅在范围的前8位中使用ASCII。感谢deceze的问题。你让我更多地考虑问题和解决方案。
package sample;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
public class UnicodeSample {
public static final int HEXADECIMAL = 16;
public static void main(String[] args) {
try {
String str = "\\u0068\\u0065\\u006c\\u006c\\u006f\\u000a\\u3fff\\uf34c";
ArrayList<Byte> arrList = new ArrayList<Byte>();
String codes[] = str.replaceAll("\\\\u"," ").trim().split(" ");
for (String c : codes) {
int code = Integer.parseInt(c,HEXADECIMAL);
byte[] bytes = intToByteArray(code);
for (byte b : bytes) {
if (b != 0) arrList.add(b);
}
}
byte[] utf8 = new byte[arrList.size()];
for (int i=0; i<arrList.size(); i++) utf8[i] = arrList.get(i);
str = new String(utf8, "UTF-8");
System.out.println(str);
}
catch (UnsupportedEncodingException e) {
// handle the exception when
}
}
// Takes a 4 byte integer and and extracts each byte
public static final byte[] intToByteArray(int value) {
return new byte[] {
(byte) (value >>> 24),
(byte) (value >>> 16),
(byte) (value >>> 8),
(byte) (value)
};
}
}
答案 2 :(得分:1)
我确定必须是更好的方法,但只使用JDK:
public static String handleEscapes(final String s)
{
final java.util.Properties props = new java.util.Properties();
props.setProperty("foo", s);
final java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
try
{
props.store(baos, null);
final String tmp = baos.toString().replace("\\\\", "\\");
props.load(new java.io.StringReader(tmp));
}
catch(final java.io.IOException ioe) // shouldn't happen
{ throw new RuntimeException(ioe); }
return props.getProperty("foo");
}
使用java.util.Properties.load(java.io.Reader)
来处理反斜杠转义(在第一次使用java.util.Properties.store(java.io.OutputStream, java.lang.String)
后反斜杠 - 转义会导致属性文件出现问题的任何内容,然后使用replace("\\\\", "\\")
来反转反斜杠 - 原始反斜杠的转义。)
(免责声明:尽管我测试了我能想到的所有案例,但仍有一些我 想到的。)