我在处理R中的转义unicode字符时遇到了问题,特别是在从MediaWiki API获取信息时遇到的问题.我会找到一个像JSON字符串
{"query":{"categorymembers":[{"ns":0,"title":"Banach\u2013Tarski paradox"}]}}
Run Code Online (Sandbox Code Playgroud)
哪个应该是完全有效的但是当fromJSON()
我通过以下方式阅读时:
snip...
[1] "Banach\023Tarski paradox"
Run Code Online (Sandbox Code Playgroud)
起初我以为这只是一个RJSONIO问题,但我遇到类似的问题scan()
和readLines()
.我的猜测是我遗漏了一些非常基本的东西.
我实际上不能仅使用R 来给出完全可重现的示例,因为如果我通过write()(或某些等效函数)将"em\u2013dash"发送到文件,则R将自动转换为em破折号.所以这里.使用以下命令创建名为test1的文本文件:
"em\u2013dash" "em–dash" " em \u2013 dash"
Run Code Online (Sandbox Code Playgroud)
然后加载R(无论文件路径是什么):
> scan( file = "~/R/test1", what = "character", encoding = "UTF-8")
Read 3 items
[1] "em\\u2013dash" "em–dash" " em \\u2013 dash"
> readLines("~/R/test1", warn = FALSE, encoding = "UTF-8")
[1] "\"em\\u2013dash\" \"em–dash\" \" em \\u2013 dash\""
Run Code Online (Sandbox Code Playgroud)
添加的转义字符是导致我的问题的原因fromJSON()
.我可以把它们剥离出来,但我可能会在这个过程中打破其他东西,我想有一个更简单的解决方案.谢谢.
这是会话信息:
R version 2.14.1 (2011-12-22)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)
locale:
[1] C/en_US.UTF-8/C/C/C/C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] RJSONIO_0.98-0
loaded via a namespace (and not attached):
[1] tools_2.14.1
Run Code Online (Sandbox Code Playgroud)
小智 9
这实际上不是RJSONIO中的错误.它的设计目的是期望一个由R读取并且已经处理过非ASCII字符的字符串.当一个字符串传递一个带有\ u的字符串时,该字符串尚未处理但已转义.在我的机器上,语言环境设置为en_US.UTF-8,命令
fromJSON('{"query":{"categorymembers":[{"ns":0,"title":"Banach\u2013Tarski paradox"}]}}')
Run Code Online (Sandbox Code Playgroud)
产生
$query
$query$categorymembers
$query$categorymembers[[1]]
$query$categorymembers[[1]]$ns
[1] 0
$query$categorymembers[[1]]$title
[1] "Banach–Tarski paradox"
Run Code Online (Sandbox Code Playgroud)
请注意,该字符的前缀为\u
not \\u
.只需输入该字符串,即可查看它在R中的显示方式.
所以问题是fromJSON()的上游,为什么字符串包含\ u.
我可以在RJSONIO中添加对处理此类未处理字符串的支持.
这是一个错误,RJSONIO
你可以清楚地看到:
> RJSONIO::fromJSON('{"x":"foo\\u2013bar"}')
x
"foo\023bar"
Run Code Online (Sandbox Code Playgroud)
它的工作原理很好rjson
:
> rjson::fromJSON('{"x":"foo\\u2013bar"}')
$x
[1] "foo–bar"
Run Code Online (Sandbox Code Playgroud)
并证明它是正确的价值:
> Sys.setlocale("LC_ALL", "C")
[1] "C/C/C/C/C/en_US.UTF-8"
> rjson::fromJSON('{"x":"foo\\u2013bar"}')
$x
[1] "foo<U+2013>bar"
Run Code Online (Sandbox Code Playgroud)
在您的分析中,您对打印字符串与实际字符串感到困惑.print
引用其打印内容 - 如果要查看实际字符串,可以使用cat
或charToRaw
.也scan
没有解释任何逃逸,所以你得到你给什么.