如何从 R 中的 JSON 数据解析十六进制代码
How to parse hex codes from JSON data in R
我已经 JSON 从网络上以如下格式抓取:
\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D
如果我复制并粘贴数据,它解析得很好:
\"datetime\":\"2019-05-12 17:00:00\"}]
然而,当我将数据作为文本文件导入时,或者当使用 rvest
从网络上抓取数据时,每个反斜杠都显示为双反斜杠:
\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D
我想知道如何让 R 将十六进制代码解析为特殊字符,即它看起来像这样:
"datetime":"2019-05-12 17:00:00"}]
我认为主要问题在于抓取,因为看起来您要导入的实际上是字符串,如“\x22”,而不是编码的“:”。
但要模拟 "what would I get if I typed this input at a prompt",您可以使用 eval
和 parse
,如下所示:
input <- readLines(file) # Or similar
# Next line for testing, note both single and double quotes
input <- '"\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D"'
result <- eval(parse(text=input))
对于文本文件中已有的数据,这是一种解决问题的方法。不过,总的来说,R 使用的反斜杠与许多其他语言略有不同:只有少数语言允许使用单个反斜杠(例如 \x##
、\u####
、\n
、\b
, \r
, \t
, 也许还有其他)。文字反斜杠是双反斜杠。由于您的文本文件有一个文字反斜杠,后跟 "x" 和一些数字,R 尽职尽责地将它们作为文字字符串读入,而不是 \x##
所代表的十六进制代码。
s <- '\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D'
这部分匹配 \x
的任何实例,但由于它是 R,我们需要 \\
来表示文字 \
... 奇怪,我知道。我们还捕获了以下两个十六进制数字:
gre <- gregexpr("\\x[0-9a-fA-F]{2}", s)
regm <- regmatches(s, gre)[[1]]
regm
# [1] "\x22" "\x22" "\x3A" "\x22" "\x2D" "\x2D" "\x20" "\x3A" "\x3A" "\x22" "\x7D"
# [12] "\x5D"
有了这个 regm
,我们可以使用十六进制转换和一些 raw
函数来转换为真正的 ascii 字符:
sapply(as.raw(strtoi(substr(regm, 3, 4), 16L)), rawToChar)
# [1] "\"" "\"" ":" "\"" "-" "-" " " ":" ":" "\"" "}" "]"
函数regmatches
不仅提取字符串中的特定模式,还可以替换它们。
regmatches(s, gre) <- list(sapply(as.raw(strtoi(substr(regm, 3, 4), 16L)), rawToChar))
s
# [1] "\"datetime\":\"2019-05-12 17:00:00\"}]"
我已经 JSON 从网络上以如下格式抓取:
\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D
如果我复制并粘贴数据,它解析得很好:
\"datetime\":\"2019-05-12 17:00:00\"}]
然而,当我将数据作为文本文件导入时,或者当使用 rvest
从网络上抓取数据时,每个反斜杠都显示为双反斜杠:
\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D
我想知道如何让 R 将十六进制代码解析为特殊字符,即它看起来像这样:
"datetime":"2019-05-12 17:00:00"}]
我认为主要问题在于抓取,因为看起来您要导入的实际上是字符串,如“\x22”,而不是编码的“:”。
但要模拟 "what would I get if I typed this input at a prompt",您可以使用 eval
和 parse
,如下所示:
input <- readLines(file) # Or similar
# Next line for testing, note both single and double quotes
input <- '"\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D"'
result <- eval(parse(text=input))
对于文本文件中已有的数据,这是一种解决问题的方法。不过,总的来说,R 使用的反斜杠与许多其他语言略有不同:只有少数语言允许使用单个反斜杠(例如 \x##
、\u####
、\n
、\b
, \r
, \t
, 也许还有其他)。文字反斜杠是双反斜杠。由于您的文本文件有一个文字反斜杠,后跟 "x" 和一些数字,R 尽职尽责地将它们作为文字字符串读入,而不是 \x##
所代表的十六进制代码。
s <- '\x22datetime\x22\x3A\x222019\x2D05\x2D12\x2017\x3A00\x3A00\x22\x7D\x5D'
这部分匹配 \x
的任何实例,但由于它是 R,我们需要 \\
来表示文字 \
... 奇怪,我知道。我们还捕获了以下两个十六进制数字:
gre <- gregexpr("\\x[0-9a-fA-F]{2}", s)
regm <- regmatches(s, gre)[[1]]
regm
# [1] "\x22" "\x22" "\x3A" "\x22" "\x2D" "\x2D" "\x20" "\x3A" "\x3A" "\x22" "\x7D"
# [12] "\x5D"
有了这个 regm
,我们可以使用十六进制转换和一些 raw
函数来转换为真正的 ascii 字符:
sapply(as.raw(strtoi(substr(regm, 3, 4), 16L)), rawToChar)
# [1] "\"" "\"" ":" "\"" "-" "-" " " ":" ":" "\"" "}" "]"
函数regmatches
不仅提取字符串中的特定模式,还可以替换它们。
regmatches(s, gre) <- list(sapply(as.raw(strtoi(substr(regm, 3, 4), 16L)), rawToChar))
s
# [1] "\"datetime\":\"2019-05-12 17:00:00\"}]"