我正在使用 Java 处理一些 Java 源代码。我正在提取字符串文字并将它们提供给采用字符串的函数。问题是我需要将字符串的未转义版本传递给函数(即这意味着将 \n
转换为换行符,并将 \\
转换为单个 \
等)。
Java API 中是否有执行此操作的函数?如果没有,我可以从一些图书馆获得这样的功能吗?显然,Java 编译器必须进行这种转换。
原文由 ziggystar 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以使用 StringEscapeUtils
来自 Apache Commons Lang 的 String unescapeJava(String)
方法。
这是一个示例片段:
String in = "a\\tb\\n\\\"c\\\"";
System.out.println(in);
// a\tb\n\"c\"
String out = StringEscapeUtils.unescapeJava(in);
System.out.println(out);
// a b
// "c"
该实用程序类具有为 Java、Java Script、HTML、XML 和 SQL 转义和取消转义字符串的方法。它还具有直接写入 java.io.Writer
的重载。
它看起来像 StringEscapeUtils
用一个 u
处理 Unicode 转义,但不是八进制转义,或者 Unicode 转义与无关的 u
.
/* Unicode escape test #1: PASS */
System.out.println(
"\u0030"
); // 0
System.out.println(
StringEscapeUtils.unescapeJava("\\u0030")
); // 0
System.out.println(
"\u0030".equals(StringEscapeUtils.unescapeJava("\\u0030"))
); // true
/* Octal escape test: FAIL */
System.out.println(
"\45"
); // %
System.out.println(
StringEscapeUtils.unescapeJava("\\45")
); // 45
System.out.println(
"\45".equals(StringEscapeUtils.unescapeJava("\\45"))
); // false
/* Unicode escape test #2: FAIL */
System.out.println(
"\uu0030"
); // 0
System.out.println(
StringEscapeUtils.unescapeJava("\\uu0030")
); // throws NestableRuntimeException:
// Unable to parse unicode value: u003
引自 JLS:
提供八进制转义是为了与 C 兼容,但只能表示 Unicode 值
\u0000
到\u00FF
,因此通常首选 Unicode 转义。
如果您的字符串可以包含八进制转义,您可能需要先将它们转换为 Unicode 转义,或者使用其他方法。
无关的 u
也记录如下:
Java 编程语言指定了一种将用 Unicode 编写的程序转换为 ASCII 的标准方法,该方法将程序更改为可以由基于 ASCII 的工具处理的形式。转换涉及通过添加额外的
u
将程序源文本中的任何 Unicode 转义符转换为 ASCII — 例如,\uxxxx
变为\uuxxxx
同时转换-while-源文本中的非 ASCII 字符到 Unicode 转义,每个字符包含一个 u。这个转换后的版本同样可以被 Java 编程语言的编译器接受,并且代表完全相同的程序。稍后可以通过转换每个转义序列从该 ASCII 形式恢复确切的 Unicode 源,其中多个
u
存在于一个少一个u
的 Unicode 字符序列,同时转换每个带有单个u
的转义序列到相应的单个 Unicode 字符。
如果您的字符串可以包含带有无关的 u
的 Unicode 转义符,那么您可能还需要在使用之前对其进行预处理 StringEscapeUtils
。
或者,您可以尝试从头开始编写自己的 Java 字符串文字转义器,确保遵循确切的 JLS 规范。
原文由 polygenelubricants 发布,翻译遵循 CC BY-SA 4.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
问题
这里作为另一个答案给出的
org.apache.commons.lang.StringEscapeUtils.unescapeJava()
几乎没有什么帮助。\0
为空。java.util.regex.Pattern.compile()
and everything that uses it, including\a
,\e
, and especially\cX
。charAt
接口而不是codePoint
接口,从而传播了 Javachar
保证包含 Unicode 字符。它不是。他们只能逃避这一点,因为没有 UTF-16 代理最终会寻找他们正在寻找的任何东西。解决方案
我写了一个 string unescaper,它解决了 OP 的问题,而没有 Apache 代码的所有烦恼。
如果它对其他人有帮助,欢迎您加入——没有任何附加条件。如果你改进它,我很乐意你把你的改进寄给我,但你当然不必这样做。