Scala - 在没有 Apache 的情况下转义 Unicode 字符串
Scala - unescape Unicode String without Apache
我有一个字符串 "b\u00f4lovar",我想知道是否可以在不使用 Commons-lang 的情况下取消转义。它可以工作,但我在某些环境中遇到问题,我想将它最小化(即:它在我的机器上工作但在生产环境中不工作)。
StringEscapeUtils.unescapeJava(variables.getOrElse("name", ""))
如果没有 apache 库,我如何取消转义?
提前致谢。
只有 Unicode 转义
如果你想反转义 only 格式的序列 \u0000
比使用单个正则表达式替换更简单:
def unescapeUnicode(str: String): String =
"""\u+([0-9a-fA-F]{4})""".r.replaceAllIn(str,
m => Integer.parseInt(m.group(1), 16).toChar match {
case '\' => """\"""
case '$' => """$"""
case c => c.toString
})
结果是
scala> unescapeUnicode("b\u00f4lovar \u30B7")
res1: String = bôlovar シ
我们必须分别处理字符 $
和 \
,因为它们被 java.util.regex.Matcher.appendReplacement
方法视为特殊字符:
def wrongUnescape(str: String): String =
"""\u([0-9a-fA-F]{4})""".r.replaceAllIn(str,
m => Integer.parseInt(m.group(1), 16).toChar.toString)
scala> wrongUnescape("\u00" + Integer.toString('$', 16))
java.lang.IllegalArgumentException: Illegal group reference: group index is missing
at java.util.regex.Matcher.appendReplacement(Matcher.java:819)
... 46 elided
scala> wrongUnescape("\u00" + Integer.toString('\', 16))
java.lang.IllegalArgumentException: character to be escaped is missing
at java.util.regex.Matcher.appendReplacement(Matcher.java:809)
... 46 elided
所有转义字符
Unicode 字符转义有点特殊:它们不是字符串文字的一部分,而是程序代码的一部分。有一个单独的阶段用字符替换unicode转义:
scala> Integer.toString('a', 16)
res2: String = 61
scala> val \u0061 = "foo"
a: String = foo
scala> // first \u005c is replaced with a backslash, and then \t is replaced with a tab.
scala> "\u005ct"
res3: String = " "
Scala 库中有一个函数 StringContext.treatEscapes
,它支持语言规范中的所有 normal escapes。
所以如果你想支持 unicode 转义和所有正常的 Scala 转义,你可以按顺序取消转义:
def unescape(str: String): String =
StringContext.treatEscapes(unescapeUnicode(str))
scala> unescape("\u0061\n\u0062")
res4: String =
a
b
scala> unescape("\u005ct")
res5: String = " "
我有一个字符串 "b\u00f4lovar",我想知道是否可以在不使用 Commons-lang 的情况下取消转义。它可以工作,但我在某些环境中遇到问题,我想将它最小化(即:它在我的机器上工作但在生产环境中不工作)。
StringEscapeUtils.unescapeJava(variables.getOrElse("name", ""))
如果没有 apache 库,我如何取消转义?
提前致谢。
只有 Unicode 转义
如果你想反转义 only 格式的序列 \u0000
比使用单个正则表达式替换更简单:
def unescapeUnicode(str: String): String =
"""\u+([0-9a-fA-F]{4})""".r.replaceAllIn(str,
m => Integer.parseInt(m.group(1), 16).toChar match {
case '\' => """\"""
case '$' => """$"""
case c => c.toString
})
结果是
scala> unescapeUnicode("b\u00f4lovar \u30B7")
res1: String = bôlovar シ
我们必须分别处理字符 $
和 \
,因为它们被 java.util.regex.Matcher.appendReplacement
方法视为特殊字符:
def wrongUnescape(str: String): String =
"""\u([0-9a-fA-F]{4})""".r.replaceAllIn(str,
m => Integer.parseInt(m.group(1), 16).toChar.toString)
scala> wrongUnescape("\u00" + Integer.toString('$', 16))
java.lang.IllegalArgumentException: Illegal group reference: group index is missing
at java.util.regex.Matcher.appendReplacement(Matcher.java:819)
... 46 elided
scala> wrongUnescape("\u00" + Integer.toString('\', 16))
java.lang.IllegalArgumentException: character to be escaped is missing
at java.util.regex.Matcher.appendReplacement(Matcher.java:809)
... 46 elided
所有转义字符
Unicode 字符转义有点特殊:它们不是字符串文字的一部分,而是程序代码的一部分。有一个单独的阶段用字符替换unicode转义:
scala> Integer.toString('a', 16)
res2: String = 61
scala> val \u0061 = "foo"
a: String = foo
scala> // first \u005c is replaced with a backslash, and then \t is replaced with a tab.
scala> "\u005ct"
res3: String = " "
Scala 库中有一个函数 StringContext.treatEscapes
,它支持语言规范中的所有 normal escapes。
所以如果你想支持 unicode 转义和所有正常的 Scala 转义,你可以按顺序取消转义:
def unescape(str: String): String =
StringContext.treatEscapes(unescapeUnicode(str))
scala> unescape("\u0061\n\u0062")
res4: String =
a
b
scala> unescape("\u005ct")
res5: String = " "