一个字符串包含多个 json,有什么办法可以把里面包含的 json 串提取出来?

2019-05-22 15:18:53 +08:00
 dynastysea

求 v2 大神指点,正则似乎可以,一个 json 也好处理。多个就不知道怎么办了

3598 次点击
所在节点    问与答
24 条回复
TomVista
2019-05-22 15:49:55 +08:00
给个字符串例子?
pierswu
2019-05-22 17:04:45 +08:00
遍历字符串,数“{”和“}”, 只要“{”的数量等于“}”的数量,就是一个 json。接着再找下一个 json
momocraft
2019-05-22 17:18:44 +08:00
正则应该不可以( JSON 已经是上下文无关文法)
数括号更不可以( JSON 内的字符串同样可能有 { )

可能可以 lex 然后数 { } token 然后一个个 try parse
shylockhg
2019-05-22 17:28:01 +08:00
1.结构化解析
2.member 访问
3.序列化 member
lululau
2019-05-22 17:38:41 +08:00
如果没有特定的分隔格式这个问题误解,假设第一个 JSON 串 123 (没错,光秃秃一个数值确实是一个合法的 JSON ),第二个 JSON 串 456,合在一起是 123456,这特么怎么区分到底是几个 JSON 串。。。
dynastysea
2019-05-22 17:46:45 +08:00
@pierswu 不行,json 里面本身也可以还有{}
dynastysea
2019-05-22 17:47:22 +08:00
@lululau 可以认为不是光秃秃的 json,就是带{},但是会比较复杂的那种 json 格式
dynastysea
2019-05-22 17:47:59 +08:00
@TomVista 比如是 sql 语句,某个字段是 json
Ultraman
2019-05-22 17:51:56 +08:00
json 里面有 json 也还是可以从前往后找,找到第一个}的时候跟它前面最后一个{匹配起来记下位置扣出来然后继续往后找
pkookp8
2019-05-22 17:56:08 +08:00
找{,记录位置入栈,如果有},则出栈,遍历字符串
栈里剩下的的都是第一个{
按记录的位置分割,解析 json
leoleoasd
2019-05-22 17:59:32 +08:00
括号匹配
双引号内的不参与匹配就好了( JSON 编码的字符串中可能有不匹配的大括号)
pkookp8
2019-05-22 18:02:18 +08:00
@pkookp8 错了,遍历字符串,每次栈空时都是一个完整的 json,记录位置,分割
goreliu
2019-05-22 18:04:04 +08:00
需要从源头解决问题,直接拼接的多个 json 字符串是不合理的。
v2nika
2019-05-22 18:05:48 +08:00
有分隔符的话直接 split 一下就好了,\r, \n, \t 这些都是 JSON 安全的分隔符,否则可以自己写个流式的 parser,但是 JSON 的边界不是那么完备,主要是 number 类型的边界是不确定的,所以如果两个 number 连在一起的话就无法识别了。但是如果可以确定顶层的数据都是 object 或者 array 的话就可以自己写一个,不需要分隔符。
Ultraman
2019-05-22 18:05:56 +08:00
或者去扒一下 json.loads()的源码看看
lululau
2019-05-22 18:11:15 +08:00
x = '{"name":"Jack\"{Sparrow}"}{"name": "Lucy"}'
in_quote = false
unmatch_left_brace = 0

x.gsub(/\\"/, '..').chars.each_with_index do |c, i|
in_quote = !in_quote if c == '"'
unmatch_left_brace += 1 if c == '{' && !in_quote
if c == '}' && !in_quote
unmatch_left_brace -= 1
puts i if unmatch_left_brace.zero?
end
end
dapang1221
2019-05-22 18:29:10 +08:00
不是,直接找}{不就行了。。。
opengps
2019-05-22 18:31:40 +08:00
从第一个{开始,遇到{加一,遇到}减一,当结果为 0 不就是一个 json 结束吗
TomatoYuyuko
2019-05-22 18:43:45 +08:00
遍历字符串遇到{就记录层数+1,遇到}就记录层数-1,层数归零就切分。
严谨一点的话还可以记录引号是否闭合来检测是否是字符“{”或“}”
ETiV
2019-05-22 18:56:13 +08:00
LZ 并不会提问题,所以无解

哪怕给个样例都可以…

————
我之前遇到的一种状况是,一串字符串,里面是 N 个 json 字典结构:

{...} {...}
{...}
{...}{...}

我的处理方法是正则替换( s/}\s*{/,/g ),再给最外层用方括号包起来,然后 JSON.parse 就出来了(会变成这些个 json 字典的数组)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/566585

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX