根据规范,以下是一些经过测试并可用的Java代码:
public static String escape(String s){
if (s == null) return s;
int len = s.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++){
char c = s.charAt(i);
if (c >= 0x20 && c < 0x80){
if (c == '\\' || c == '{' || c == '}'){
sb.append('\\');
}
sb.append(c);
}
else if (c < 0x20 || (c >= 0x80 && c <= 0xFF)){
sb.append("\'");
sb.append(Integer.toHexString(c));
}else{
sb.append("\\u");
sb.append((short)c);
sb.append("??");
}
}
return sb.toString();
}
重要的是,您需要在转义的Unicode字符后附加2个字符(靠近Unicode字符或只使用?代替),因为Unicode占用2个字节。
此外,规范指出,如果代码点大于32767,则应使用负值,但在我的测试中,如果不使用负值也可以。
以下是规范:
\uN:此关键字表示单个Unicode字符,该字符基于当前ANSI代码页没有等效的ANSI表示。 N表示以十进制数表示的Unicode字符值。
紧接着此关键字是ANSI表示中的等效字符。通过这种方式,旧读者将忽略\uN关键字并正确获取ANSI表示。当遇到此关键字时,读者应忽略下一个N个字符,其中N对应于上次遇到的\ucN值。
和所有RTF关键词一样,可能存在一个关键字终止空格(在ANSI字符之前),该空格不计入要跳过的字符数。虽然这种情况不太可能发生(或建议),但\bin关键字、其参数和随后的二进制数据被认为是一个用于跳过目的的字符。如果在扫描可跳过数据时遇到RTF作用范围分隔符字符(即打开或关闭大括号),则跳过的数据被视为在定界符之前结束。这使得读者可以执行一些基本的错误恢复。要在可跳过的数据中包含RTF定界符,必须使用适当的控制符号表示它(即用反斜杠转义),就像普通文本一样。任何RTF控制词或符号都被视为计算可跳过字符的单个字符。
当遇到没有相应ANSI字符的Unicode字符时,RTF写入器应输出\uN,后面跟着它能够处理的最佳ANSI表示形式。此外,如果Unicode字符翻译成的ANSI字符流的字节计数与当前Unicode字符字节计数不同,则应在\uN关键字之前发出\ucN关键字,以通知读者更改。
RTF控制字符通常采用带符号的16位数字作为参数。因此,大于32767的Unicode值必须表示为负数。