我想替换所有出现的“\ uXXXX”类型的正则表达式,其中“XXXX”是 表示相应字符的Unicode字符的十六进制数。
我尝试了以下Scala代码:
def unscape(s : String) : String = {
val rex = """\\u([0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z])""".r
rex.replaceAllIn(s,m => {
hex2str(m.group(1))
}
}
def hex2str(s:String): String = {
Integer.parseInt(s,16).toChar.toString
}
如果我尝试,例如:
unscape("Hi\\u0024, \\u0024")
它给出了以下例外:
java.lang.StringIndexOutOfBoundsException: String index out of range: 1
在this other question中,似乎Java处理Unicode字符可能存在错误。那是问题吗?
答案 0 :(得分:2)
只是调整接受的答案:
def unscape3(s: String): String = {
val rex = """\\u(\p{XDigit}{4})""".r
rex.replaceAllIn(s, m => Regex quoteReplacement hex2str(m group 1))
}
Console println unscape3("""Hi\u0024, \u0024""")
请注意,字符类是正确的,您在使用quoteReplacement
时无需了解需要转义的内容。
(可能比多次扫描替换文字更有效。)
答案 1 :(得分:1)
请尝试以下操作:
def unscape(s: String): String = {
val rex = """\\u([0-9a-fA-F]{4})""".r
rex.replaceAllIn(s, m => {
hex2str(m.group(1))
.replaceAllLiterally("\\", "\\\\")
.replaceAllLiterally("$", "\\$")
})
}
根据replaceAllIn
使用的Matcher.appendReplacement:
请注意替换中的反斜杠(\)和美元符号($) 字符串可能会导致结果与正确的结果不同 作为文字替换字符串处理。可以对待美元符号 作为对如上所述的捕获的子序列的引用,和 反斜杠用于替换替换中的文字字符 字符串。