使用内联引号将 JSON 导入 R

Posted

技术标签:

【中文标题】使用内联引号将 JSON 导入 R【英文标题】:Importing JSON into R with in-line quotation marks 【发布时间】:2014-10-07 20:58:28 【问题描述】:

我正在尝试将以下 JSON 文件(“my_file.json”)读入 R,其中包含以下内容:

["id":"484","comment":"They call me "Bruce""]

使用jsonlite包(0.9.12),以下失败:

library(jsonlite)
fromJSON(readLines('~/my_file.json'))

收到错误:

"Error in parseJSON(txt) : lexical error: invalid char in json text.
84","comment":"They call me "Bruce""]
           (right here) ------^"

这是文件R转义的输出:

readLines('~/my_file.json')

"[\"id\":\"484\",\"comment\":\"They call me \"Bruce\"\"]"

删除“布鲁斯”周围的引号可以解决问题,如下所示:

my_file.json

["id":"484","comment":"They call me Bruce"]

但是擒纵机构有什么问题呢?

【问题讨论】:

["id":"484","comment":"They call me "Bruce""] 是无效的 json jsonlint.com Ref: Escaping quotation marks in JSON + 在JSONlint 中尝试您的 JSON 字符串。它不会用jsonliteRJSONIOrjson 解析。 【参考方案1】:

在 R 中 strings literals 可以使用单引号或双引号来定义。 例如

s1 <- 'hello'
s2 <- "world"

当然,如果您想在使用双引号定义的字符串文字中包含双引号,您需要转义(使用反斜杠)内引号,否则 R 代码解析器将无法检测到字符串的结尾正确(单引号也是如此)。 例如

s1 <- "Hello, my name is \"John\""

如果你在控制台上打印(使用cat¹)这个字符串,或者你把这个字符串写在一个文件上,你将得到字符串的实际“面”,而不是 R 文字表示,即:

> cat("Hello, my name is \"John\"")
Hello, my name is "John"

json 解析器读取字符串的实际“面”,因此,在您的情况下,json 读取:

["id":"484","comment":"They call me "Bruce""]

不是(R 文字表示):

"[\"id\":\"484\",\"comment\":\"They call me \"Bruce\"\"]" 

话虽如此,当字符串中有引号时,json 解析器也需要转义双引号。

因此,您的字符串应该以这种方式修改:

["id":"484","comment":"They call me \"Bruce\""]

如果您只是通过添加反斜杠来修改文件,您将完全能够读取 json。

请注意,该字符串对应的 R 字面量表示为:

"[\"id\":\"484\",\"comment\":\"They call me \\\"Bruce\\\"\"]"

事实上,这是可行的:

> fromJSON("[\"id\":\"484\",\"comment\":\"They call me \\\"Bruce\\\"\"]")
   id              comment
1 484 They call me "Bruce"

¹ 默认的 R print 函数(在您只需按 ENTER 键时也会调用)返回相应的 R 字符串文字。如果要打印实际字符串,需要使用print(quote=F,stringToPrint),或者cat函数。


编辑(@EngrStudent 评论自动转义引号的可能性):

Json 解析器无法自动转义引号。 我的意思是,试着设身处地为计算机着想,你应该将这个(未转义的)字符串解析为 json: "foo1" : " : "foo2" : "foo3"

我看到至少三个可能的转义给了一个有效的 json: "foo1" : " : \"foo2\" : \"foo3" "foo1\" : " : "foo2\" : \"foo3" "foo1\" : \" : \"foo2" : "foo3"

从这个小例子可以看出,为了避免歧义,转义确实是必要的。

也许,如果您要转义的字符串具有非常特殊的结构,您可以识别(没有不确定性)需要转义的双引号,您可以创建自己的自动转义过程,但您需要从头开始,因为没有内置任何东西。

【讨论】:

非常感谢 - 非常有帮助。我现在看到我从无效的 JSON 开始。但是,我正在处理大量散布在此结构中的数据。我是否只需要构建一小段代码来搜索正则表达式并正确转义数据集? @user3741038:是的,我想你应该这样做,即使我认为这并不容易...... 对于大型 json 有没有办法制作非手动的反斜杠?

以上是关于使用内联引号将 JSON 导入 R的主要内容,如果未能解决你的问题,请参考以下文章

在引号之间将csv列导入为整数

使用 laravel json 导入双引号

带引号的Thymeleaf内联javascript不起作用

从 JSON 对象中删除空格,但不在引号内

python请求json返回单引号

关于requests.post().json()获取到的JSON为单引号和NONE的那些事