从远程json读取并在R中使用jsonlite :: fromJSON()时,跳过的字符无法正确解释

时间:2014-07-20 18:01:39

标签: json r unicode escaping

我正试图从twitter firehose的api页面读取一些json。在我下载的推文中,有许多没有英文字符。例如:

  

“text”:“Vaccini:perch \ u00e9 fare l \ u2019esavalente quando gli   obbligatori sono solo quattro? http://t.co/dLdzoXOUUK来自   @wireditalia“

当我通过R中的readLines导入推文数据并打印出来时,我看到:

  

\\“text \\”:\\“Vaccini:perch \\ u00e9 fare l \\ u2019esavalente quando gli   obbligatori sono solo quattro? http://t.co/dLdzoXOUUK来自   @wireditalia \\“

因此,反斜杠和引号都被转义。如果我只使用cat()打印,则不再存在转义。所以我认为print()存在问题。 但是当我用fromJSON解析它时,我发现像\ u00e9这样的字符串变成了\ xe9。我试图理解为什么,通过一些测试,我注意到了

fromJSON('["\\u00e9"]') 

打印

"\xe9"

fromJSON('["\\u2019"]') 

打印

"\031"

而不是分别为“'”和“é”,应该如此。所以jsonlite :: fromJSON误解了那些双反斜杠。

但问题是双反斜杠本身!为什么R首先逃脱了一切?我甚至不能gsub('\ u','\ u',text,fixed = T)但它返回:

  

错误:'\ u'在字符串开头“'\ u”

时没有使用十六进制数字

因为它看起来像是一个特殊的字符,并且不允许用作替代品!

此外,R的默认转义也会使我的脚本在遇到一个将其设置为位置的用户时失败:

"location":"V\u03b1l\u03c1\u03bfl\u03b9c\u03b5ll\u03b1-V\u03b5r\u03bfn\u03b1 /=\\","default_profile_image":false

在她的推特档案中是:

  

Vαlροlιcεllα-Vεrοnα/ = \

源代码中的那个\“在R上显示为/ = \',因此打破了json。

所以,我需要一种逃避这种逃避问题的方法!

1 个答案:

答案 0 :(得分:1)

问题在于您的输入数据。您在R中读取的文本不应具有\u值作为纯文本。这是不正确的。当R显示一个\u的值,它是UTF字符的转义序列时,文本中实际上没有任何斜杠或“u”。

但是如果您需要读取R中的错误数据,则可以找到所有\u值后跟十六进制数字,并用适当的Unicode字符替换它们。例如,假设您在T

中有字符串
tt<-"\\u00e9 and \\u2019 and \\u25a0"

如果cat() R中的值删除转义,您会看到包含

cat(tt)
#\u00e9 and \u2019 and \u25a0

因此文本中有“\ u”值(它们不是真正的unicode字符)。我们可以用

找到并替换它们
m <- gregexpr("\\\\u[0-9A-Fa-f]{4}", tt)
regmatches(tt,m) <- lapply(
    lapply(regmatches(tt,m), substr,3, 999), function(x)  
    intToUtf8(as.integer(as.hexmode(x)), multiple=TRUE))
tt
# [1] "é and ’ and ■"

这将找到所有“\ u”值并替换它们。

重要的是要注意

fromJSON('["\\u2019"]')

不是unicode角色。通过执行双反斜杠,您已经逃脱了转义字符,因此您只是字面上有斜线-u。要获得真正的unicode角色,你需要

fromJSON('["\u2019"]') 

如果您的数据在加载到R之前已经过正确编码,那么这不是问题。我不明白你用什么来下载推文,但很明显它搞砸了。