转义十六进制,如u…用kotlin弦



我有一个字符串"ufffdufffd hellon"

我有一个像这样的代码

fun main() {
val bs = "ufffdufffd hellon"
println(bs) // �� hello
}

和我想看到"ufffdufffd hello",我怎么能转义u为每个十六进制值

乌利希期刊指南:

val s = """uffcd"""
val req = """(?<!\\)(\\\\)*(\u)([A-Fa-f\d]{4})""".toRegex()
return s.replace(unicodeRegex, """$1\\u$3""")

(我将这个问题解释为询问如何清楚地显示包含不可打印字符的字符串。Kotlin编译器将u序列与字符串字面量中的4个十六进制数字转换为单个字符,因此问题是有效地询问如何再次将它们转换回来。

不幸的是,没有内置的方法可以做到这一点。写一个很容易,但有点主观,因为没有一个关于什么是"可打印"的定义…

下面是一个扩展函数,大致可以满足您的需求:

fun String.printable() = map {
when (Character.getType(it).toByte()) {
Character.CONTROL, Character.FORMAT, Character.PRIVATE_USE,
Character.SURROGATE, Character.UNASSIGNED, Character.OTHER_SYMBOL
-> "\u%04x".format(it.toInt())
else -> it.toString()
}
}.joinToString("")
println("ufffdufffd hellon".printable()) // prints ‘ufffdufffd hellou000a’

问题中的示例字符串是一个不好的例子,因为uFFFD是替换字符—一个带问号的黑色菱形,通常显示在任何不可显示的字符的位置。所以替换字符本身可显示的!

上面的代码通过排除Character.OTHER_SYMBOL类型将其视为不可显示的-但这也将排除许多其他符号。所以你可能会想要移除它,只留下其他5种类型。(我是从这个答案中得到的。)

因为后面的换行符是不可显示的,它也被转换为十六进制代码。您可以扩展代码以处理转义码t,b,n,r,如果需要,也可以处理\。(你也可以让它更有效率…这是为了简洁!)

只需在字符串前添加另一个反斜杠来转义:

val bs = "\ufffd\ufffd hellon"

您也可以使用"""的原始字符串,这样您就不必转义反斜杠(这对regex很有用):

val bs = """ufffdufffd hellon"""

注意,在这种情况下,n也不会被计算为LF字符,并且将被打印为两个字符"n"。但是,如果您想要实际换行,可以在原始字符串中添加文字换行符:

val bs = """ufffdufffd hello
"""

最新更新