Kotlin字符串中如何转义\u开头十六进制Unicode值使其原样输出
问题根因
Kotlin 编译器在编译阶段会自动将普通字符串字面量中的\uXXXX转义序列转换为对应的 Unicode 字符,运行时你拿到的字符串中存储的是实际的字符实体,不存在\u前缀的文本内容,因此你之前用正则匹配\u的方案无法生效。
可行解决方案
分两种场景处理:
场景1:已编译字符串转Unicode字面量
如果你的字符串是普通字面量声明的(编译后转义已经被解析),需要将实际字符反向转换为\uXXXX的字面量格式,实现如下:
fun String.toUnicodeLiteral(): String { return buildString { this@toUnicodeLiteral.forEach { char -> when { // 可打印ASCII字符保留原格式,不需要可删除此分支全量转义 char in ' '..'~' -> append(char) // 其余字符统一转为\u+四位十六进制格式 else -> append("\\u%04x".format(char.code)) } } } } fun main() { val bs = "\ufffd\ufffd hello\n" println(bs.toUnicodeLiteral()) // 输出结果:\ufffd\ufffd hello\u000a // 如果需要保留换行、制表符等常规转义的原格式,补充when分支单独处理即可 }
场景2:原始字符串的转义处理
如果你的字符串是用三个引号包裹的原始字符串(编译时不会解析\u转义,内存中实际存在\u文本),修正正则实现如下:
fun escapeRawUnicode(str: String): String { val unicodeRegex = """(?<!\\)(\\\\)*(\\u)([A-Fa-f\d]{4})""".toRegex() return unicodeRegex.replace(str) { match -> val prefix = match.groupValues[1] val code = match.groupValues[3] "${prefix}\\\\u${code}" } } fun main() { val rawStr = """\uffcd hello \\\\u1234""" println(escapeRawUnicode(rawStr)) // 输出结果:\\uffcd hello \\\\u1234 }
最简方案
如果只是想在代码中声明字符串时不解析\u转义,直接用原始字符串包裹即可,不需要额外处理逻辑:
val bs = """\ufffd\ufffd hello\n""" println(bs) // 直接输出:\ufffd\ufffd hello\n
内容的提问来源于stack exchange,提问作者vl4deee11
相关产品推荐
相关产品推荐

