取消转义字符串中的 unicode
Posted
技术标签:
【中文标题】取消转义字符串中的 unicode【英文标题】:Unescape unicode in character string 【发布时间】:2014-09-17 02:21:35 【问题描述】:RJSONIO
中有一个长期存在的bug 用于解析包含 unicode 转义序列的 json 字符串。似乎需要在 libjson
中修复该错误,这可能不会很快发生,所以我正在寻找在 R 中创建一个解决方法,在将它们提供给 json 解析器之前取消转义 \uxxxx
序列。
一些上下文:json数据总是unicode,默认使用utf-8
,所以一般不需要转义。但由于历史原因,json 确实支持转义的 unicode。因此json数据
"x" : "Zürich"
和
"x" : "Z\u00FCrich"
是等效的,并且在解析时应该产生完全相同的输出。但无论出于何种原因,后者在RJSONIO
中不起作用。额外的confusion 是由于 R 本身也支持转义的 unicode 造成的。因此,当我们在 R 控制台中键入 "Z\u00FCrich"
时,它会自动正确地转换为 "Zürich"
。为了得到实际的 json 字符串,我们需要转义反斜杠本身,它是 json 中 unicode 转义序列的第一个字符:
test <- '"x" : "Z\\u00FCrich"'
cat(test)
所以我的问题是:给定 R 中的一个大 json 字符串,我怎样才能对所有转义的 unicode 序列进行转义? IE。如何用相应的 unicode 字符替换所有出现的\uxxxx
?同样,这里的\uxxxx
代表一个实际的 6 个字符的字符串,以反斜杠开头。所以unescape
函数应该满足:
#Escaped string
escaped <- "Z\\u00FCrich"
#Unescape unicode
unescape(escaped) == "Zürich"
#This is the same thing
unescape(escaped) == "Z\u00FCrich"
可能使事情复杂化的一件事是,如果反斜杠本身在 json 中用另一个反斜杠转义,则它 不是 unicode 转义序列的一部分。例如。 unescape
也应该满足:
#Watch out for escaped backslashes
unescape("Z\\\\u00FCrich") == "Z\\\\u00FCrich"
unescape("Z\\\\\\u00FCrich") == "Z\\\\ürich"
【问题讨论】:
我在这里遇到了类似的问题:***.com/questions/20067206/… 不确定是否有任何简单的解决方案。 这是一个不同的问题。您正在尝试解析无效的 JSON。 【参考方案1】:stringi
包中有这个功能:)
require(stringi)
escaped <- "Z\\u00FCrich"
escaped
## [1] "Z\\u00FCrich"
stri_unescape_unicode(escaped)
## [1] "Zürich"
【讨论】:
这在后面的测试中失败了,因为它也取消了换行符、制表符、反斜杠等。但是json
需要那些保持转义。我只想取消转义 \u
序列,没有别的。【参考方案2】:
可能是这样的?
\"x\"\s:\s\"([^"]*?)\"
这不是寻找字母。只等报价
【讨论】:
【参考方案3】:在玩了更多之后,我认为我能做的最好的事情是使用正则表达式搜索\uxxxx
模式,然后使用 R 解析器解析它们:
unescape_unicode <- function(x)
#single string only
stopifnot(is.character(x) && length(x) == 1)
#find matches
m <- gregexpr("(\\\\)+u[0-9a-z]4", x, ignore.case = TRUE)
if(m[[1]][1] > -1)
#parse matches
p <- vapply(regmatches(x, m)[[1]], function(txt)
gsub("\\", "\\\\", parse(text=paste0('"', txt, '"'))[[1]], fixed = TRUE, useBytes = TRUE)
, character(1), USE.NAMES = FALSE)
#substitute parsed into original
regmatches(x, m) <- list(p)
x
这似乎适用于所有情况,我还没有发现任何奇怪的副作用
【讨论】:
以上是关于取消转义字符串中的 unicode的主要内容,如果未能解决你的问题,请参考以下文章
Python 2.7:如何将字符串中的 unicode 转义转换为实际的 utf-8 字符