所以我有run into a similar problem before,并且我打算编写一个相当函数来使用Jeroen 的修复来尝试修复JSON。由于我还是打算这样做,所以这里有一个快速的 hack 尝试。
注意:修复这样的结构化格式充其量只是推测性的,而且肯定容易出错。好消息是我试图保持足够具体,这样它就不会产生错误的结果:它要么修复它知道它可以修复的东西,要么失败。 “单元测试”确实需要检查其他极端情况。如果您发现某些问题无法解决(并且应该)或无法解决(喘气!),请发表评论!
fix_json_quotes <- function(s) {
if (length(s) != 1) {
warning("the argument has length > 1 and only the first element will be used")
s <- s[[1]]
}
stopifnot(is.character(s))
val <- jsonlite::validate(s)
while (! val) {
ind <- attr(val, "offset") - 1
snew <- gsub("(.*)(['\"])([[:space:],]*)$", "\\1\\\\\\2\\3", substr(s, 1, ind))
if (snew != substr(s, 1, ind)) {
s <- paste0(snew, substr(s, ind + 1, nchar(s)))
} else {
break
}
val <- jsonlite::validate(s)
}
if (! val) {
# still not validating
stop("unable to fix quotes")
}
return(s)
}
一些示例数据,如果您愿意,可以进行单元测试(testthat 不需要使用该功能):
library(testthat)
lst <- list(a="final \"cliff bill\" on")
json <- as.character(toJSON(lst))
json
# [1] "{\"a\":[\"final \\\"cliff bill\\\" on\"]}"
好的,应该没有变化:
expect_equal(json, fix_json_quotes(json))
一些不良数据:
# un-escape the double quotes
badlst <- "{\"a\":[\"final \"cliff bill\" on\"]}"
expect_error(jsonlite::fromJSON(badlst))
expect_equal(json, fix_json_quotes(badlst))
PS:这看起来专门用于双引号,仅此而已。但是,我相信这可能也可以修复相关的错误。我为此“留出了空间”,在正则表达式的第二组中(([\"]));例如,如果单引号也可能导致问题,则可以将组更改为([\"'])。我不知道它是否有用甚至是必要的。