我有一个字符串" 1234567(Asics(アシックスワーキング))"。它有unicode字符,有些是ASCII的一部分,有些则不是。 java的作用是ASCII字符需要一个字节,其他unicode字符需要两个字节。
我程序的某些部分无法以此格式处理字符串。所以我想将值编码为转义序列。
所以字符串
" 1234567(Asics(アシックスワーキング))"
将映射到
" \ u0031 \ u0032 \ u0033 \ u0034 \ u0035 \ u0036 \ u0037 \ u0028 \ u0041 \ u0073 \ u0069 \ u0063 \ u0073 \ u0020 \ u0028 \ u30a2 \ u30b7 \ u30c3 \ u30af \ u30b9 \ u30ef \ u30fc \ u30ad \ u30f3 \ u30b0 \ u0029 \ u0020 \ u0029"
我写了这个函数来做到这一点: -
public static String convertToEscaped(String utf8) throws java.lang.Exception
{
char[] str = utf8.toCharArray();
StringBuilder unicodeStringBuilder = new StringBuilder();
for(int i = 0; i < str.length; i++){
char charValue = str[i];
int intValue = (int) charValue;
String hexValue = Integer.toHexString(intValue);
unicodeStringBuilder.append("\\u");
for (int length = hexValue.length(); length < 4; length++) {
unicodeStringBuilder.append("0");
}
unicodeStringBuilder.append(hexValue);
}
return unicodeStringBuilder.toString();
}
这在我的程序之外工作正常但在我的程序中引起了问题。发生在char[] str = utf8.toCharArray();
行
不知何故,我失去了我的日语unicode角色,这种情况正在发生,因为t将这些字符分成char数组中的2个。
所以我决定改为使用byte []
。
public static String convertToEscaped(String utf8) throws java.lang.Exception
{
byte str[] = utf8.getBytes();
StringBuilder unicodeStringBuilder = new StringBuilder();
for(int i = 0; i < str.length - 1 ; i+=2){
int intValue = (int) str[i]* 256 + (int)str[i+1];
String hexValue = Integer.toHexString(intValue);
unicodeStringBuilder.append("\\u");
for (int length = hexValue.length(); length < 4; length++) {
unicodeStringBuilder.append("0");
}
unicodeStringBuilder.append(hexValue);
}
return unicodeStringBuilder.toString();
}
输出: \ u3132 \ u3334 \ u3536 \ u3738 \ u2841 \ u7369 \ u6373 \ u2028 \ uffffe282 \ uffffa1e3 \ uffff81b7 \ uffffe283 \ uffff82e3 \ uffff81af \ uffffe282 \ uffffb8e3 \ uffff82af \ uffffe283 \ uffffbbe3 \ uffff81ad \ uffffe283 \ uffffb2e3 \ uffff81b0 \ u2920
但这也是错误的,因为我将两个单字节字符合并为一个。我该怎么做才能克服这个问题?
答案 0 :(得分:5)
我不了解您的其他代码的具体要求。但我的建议是不要重新发明轮子并使用API的内置编码功能。
例如,根据您需要的字节顺序,使用getBytes
或StandardCharsets.UTF_16BE
来调用StandardCharsets.UTF_16LE
:
String s = "1234567(Asics (アシックスワーキング) )";
byte[] utf8 = s.getBytes(StandardCharsets.UTF_8);
byte[] utf16 = s.getBytes(StandardCharsets.UTF_16BE); // high order byte first
System.out.println(s.length()); // 28
System.out.println(utf8.length); // 48
System.out.println(utf16.length); // 56 (2 bytes for each char)
答案 1 :(得分:0)
正如他们在上面评论的那样,java中字符串的内部表示形式是utf-16。结果
Character.codePointAt()和Integer.toHexString()在您的案例中很有用。
将参数重命名为theString,同时从原始方法中删除了throws Exception子句,因为没有抛出异常。 (抛出这些通用异常通常是不好的做法)
public static String convertToEscaped(String theString) {
char[] charArr = theString.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < charArr.length; i++) {
String hexString = Integer.toHexString(Character.codePointAt(charArr, i));
sb.append("\\u");
if (hexString.length() == 2) {
sb.append("00");
}
sb.append(hexString);
}
return sb.toString();
}