V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
dynastysea
V2EX  ›  问与答

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

  •  
  •   dynastysea · 2019-05-22 15:18:53 +08:00 · 3721 次点击
    这是一个创建于 2044 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    可能可以 lex 然后数 { } token 然后一个个 try parse
    shylockhg
        4
    shylockhg  
       2019-05-22 17:28:01 +08:00
    1.结构化解析
    2.member 访问
    3.序列化 member
    lululau
        5
    lululau  
       2019-05-22 17:38:41 +08:00
    如果没有特定的分隔格式这个问题误解,假设第一个 JSON 串 123 (没错,光秃秃一个数值确实是一个合法的 JSON ),第二个 JSON 串 456,合在一起是 123456,这特么怎么区分到底是几个 JSON 串。。。
    dynastysea
        6
    dynastysea  
    OP
       2019-05-22 17:46:45 +08:00
    @pierswu 不行,json 里面本身也可以还有{}
    dynastysea
        7
    dynastysea  
    OP
       2019-05-22 17:47:22 +08:00
    @lululau 可以认为不是光秃秃的 json,就是带{},但是会比较复杂的那种 json 格式
    dynastysea
        8
    dynastysea  
    OP
       2019-05-22 17:47:59 +08:00
    @TomVista 比如是 sql 语句,某个字段是 json
    Ultraman
        9
    Ultraman  
       2019-05-22 17:51:56 +08:00
    json 里面有 json 也还是可以从前往后找,找到第一个}的时候跟它前面最后一个{匹配起来记下位置扣出来然后继续往后找
    pkookp8
        10
    pkookp8  
       2019-05-22 17:56:08 +08:00 via Android
    找{,记录位置入栈,如果有},则出栈,遍历字符串
    栈里剩下的的都是第一个{
    按记录的位置分割,解析 json
    leoleoasd
        11
    leoleoasd  
       2019-05-22 17:59:32 +08:00 via Android
    括号匹配
    双引号内的不参与匹配就好了( JSON 编码的字符串中可能有不匹配的大括号)
    pkookp8
        12
    pkookp8  
       2019-05-22 18:02:18 +08:00 via Android
    @pkookp8 错了,遍历字符串,每次栈空时都是一个完整的 json,记录位置,分割
    goreliu
        13
    goreliu  
       2019-05-22 18:04:04 +08:00 via iPhone
    需要从源头解决问题,直接拼接的多个 json 字符串是不合理的。
    v2nika
        14
    v2nika  
       2019-05-22 18:05:48 +08:00
    有分隔符的话直接 split 一下就好了,\r, \n, \t 这些都是 JSON 安全的分隔符,否则可以自己写个流式的 parser,但是 JSON 的边界不是那么完备,主要是 number 类型的边界是不确定的,所以如果两个 number 连在一起的话就无法识别了。但是如果可以确定顶层的数据都是 object 或者 array 的话就可以自己写一个,不需要分隔符。
    Ultraman
        15
    Ultraman  
       2019-05-22 18:05:56 +08:00 via Android
    或者去扒一下 json.loads()的源码看看
    lululau
        16
    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
        17
    dapang1221  
       2019-05-22 18:29:10 +08:00
    不是,直接找}{不就行了。。。
    opengps
        18
    opengps  
       2019-05-22 18:31:40 +08:00 via Android
    从第一个{开始,遇到{加一,遇到}减一,当结果为 0 不就是一个 json 结束吗
    TomatoYuyuko
        19
    TomatoYuyuko  
       2019-05-22 18:43:45 +08:00
    遍历字符串遇到{就记录层数+1,遇到}就记录层数-1,层数归零就切分。
    严谨一点的话还可以记录引号是否闭合来检测是否是字符“{”或“}”
    ETiV
        20
    ETiV  
       2019-05-22 18:56:13 +08:00 via iPhone
    LZ 并不会提问题,所以无解

    哪怕给个样例都可以…

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

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

    我的处理方法是正则替换( s/}\s*{/,/g ),再给最外层用方括号包起来,然后 JSON.parse 就出来了(会变成这些个 json 字典的数组)
    weyou
        21
    weyou  
       2019-05-22 19:03:21 +08:00 via Android
    字符串直接放到一对[]中间组成一个新的 json 字符串,然后用 json 解析不就好了。
    ochatokori
        22
    ochatokori  
       2019-05-22 19:03:48 +08:00 via Android
    2 楼 数括号我觉得是可以的啊,因为不管里面有多少对{},只有到了最外面的}左右大括号数量才会相等
    IsaacYoung
        23
    IsaacYoung  
       2019-05-22 19:06:29 +08:00 via iPhone
    注意数组[]这种也是合法 json
    vakara
        24
    vakara  
       2019-05-23 08:49:13 +08:00 via Android
    遍历大括号的对数,不过有一点,就是要考虑在 "" 里面的情况,在遍历的时候记录下当前是否在 "" 内,如果在内就不记录。 还有,要考虑 \" 的情况。
    这种处理起来比较复杂…
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5807 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 02:40 · PVG 10:40 · LAX 18:40 · JFK 21:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.