Jer*_*oen 8 regex unicode json r utf-8
有一个长期的错误在RJSONIO
解析包含Unicode转义序列JSON字符串.似乎需要修复bug,libjson
这可能不会很快发生,因此我正在寻找在R中创建一个解决方法,\uxxxx
在将它们提供给json解析器之前对其进行unescapes 序列.
一些上下文:json数据总是unicode,utf-8
默认使用,因此通常不需要转义.但由于历史原因,json确实支持转义的unicode.因此json数据
{"x" : "Zürich"}
Run Code Online (Sandbox Code Playgroud)
和
{"x" : "Z\u00FCrich"}
Run Code Online (Sandbox Code Playgroud)
是等价的,并且在解析时应该产生完全相同的输出.但无论出于何种原因,后者都不起作用RJSONIO
.另外一个混乱是由于R本身也支持转义的unicode.因此,当我们输入"Z\u00FCrich"
R控制台时,它会自动正确转换为"Zürich"
.为了获得实际的json字符串,我们需要转义反斜杠本身,它是json中unicode转义序列的第一个字符:
test <- '{"x" : "Z\\u00FCrich"}'
cat(test)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:在R中给出一个大的json字符串,我怎样才能解除所有转义的unicode序列?即我如何\uxxxx
用相应的unicode字符替换所有出现的?同样,\uxxxx
这里表示一个6个字符的实际字符串,以反斜杠开头.所以一个unescape
函数应该满足:
#Escaped string
escaped <- "Z\\u00FCrich"
#Unescape unicode
unescape(escaped) == "Zürich"
#This is the same thing
unescape(escaped) == "Z\u00FCrich"
Run Code Online (Sandbox Code Playgroud)
可能使事情复杂化的一件事是,如果反斜杠本身在json中使用另一个反斜杠进行转义,则它不是 unicode转义序列的一部分.例如,unescape
还应满足:
#Watch out for escaped backslashes
unescape("Z\\\\u00FCrich") == "Z\\\\u00FCrich"
unescape("Z\\\\\\u00FCrich") == "Z\\\\ürich"
Run Code Online (Sandbox Code Playgroud)
在玩了一些之后,我认为我能做的最好的就是\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
}
Run Code Online (Sandbox Code Playgroud)
这似乎适用于所有情况,我还没有发现任何奇怪的副作用
归档时间: |
|
查看次数: |
1133 次 |
最近记录: |