【问题标题】:PHP: How to extract JSON strings out of a string dumpPHP:如何从字符串转储中提取 JSON 字符串
【发布时间】:2013-10-13 04:37:29
【问题描述】:

我有一个巨大的字符串转储,其中包含常规文本和 JSON 的混合。我想从字符串转储中分离/删除 JSON 对象并仅获取文本。

这是一个例子:

This is some text {'JSON':'Object'} Here's some more text {'JSON':'Object'} Yet more text {'JSON':'Object'} Again, some text.

我的目标是得到一个看起来像这样的文本转储(基本上 JSON 已被删除):

This is some text Here's some more text Yet more text Again, some text.

我需要在 PHP 中完成这一切。文本转储总是随机的,JSON 数据结构也是如此(其中大部分是深度嵌套的)。转储可能以 JSON 开头,也可能不以 JSON 开头,字符串转储中可能包含也可能不包含多个 JSON 对象。

我尝试在字符串上使用json_decode,但结果最终为NULL

编辑:Amal 的答案非常接近我想要的(见下面的第二条评论):

$str = preg_replace('#\{.*?\}#s', '', $str);

但是,它根本没有摆脱嵌套对象;例如括号内的数据:[]或[{}]

抱歉,我不是正则表达式专家。

我意识到你们中的一些人可能需要我正在处理的字符串转储的更具体示例;因此我创建了一个要点(请注意,这不是静态数据;转储中的数据总是不同的;我上面的示例只是简化了我正在使用的字符串):https://gist.github.com/anonymous/6855800

【问题讨论】:

  • 你试过了吗?
  • $str = preg_replace('#\{.*?\}#s', '', $str);?
  • 杰瑞:我试过json_decode,但没用。 Amal:那种工作,但它似乎并没有摆脱括号中包含的嵌套数据 [] 或 [{}]
  • 介意显示你用过的代码吗?
  • 杰瑞:我在问这个问题之前使用的代码很简单:$string = json_decode($json, true);。而已;除此之外,实际的字符串转储长度约为 13,000 个字符,位于 json_decode 行之前。

标签: php regex json string


【解决方案1】:

这是一个基于animesh seth的回答的工作代码sn-p。

if (strpos($msg, '{') !== false) {
    $msg = str_split($msg);
    // extract the json message.
    $json = '';
    $in = 0;
    foreach ($msg as $i => $char) {
        if ($char == '{') {
            $in++;
        }
        if ($in) {
            $json .= $msg[$i];
        }
        if ($char == '}') {
            $in--;
        }
    }
    if ($json) {
        $json = json_decode($json);
    }
    // do something with the json object.
}

【讨论】:

    【解决方案2】:

    我希望您使用 JSON_decode 发布您在尝试中使用的代码,但是哦,好吧...

    您可以在 PHP 中为嵌套大括号使用递归正则表达式:

    $res = preg_replace('~\{(?:[^{}]|(?R))*\}~', '', $text);
    

    regex101 demo(以蓝色突出显示的部分将被删除)。

    【讨论】:

    • 杰瑞,代码很简单: $string = ""; $result = json_decode($string, true); // 就是这样。
    • @JamesNine 我认为您会收到错误 4,这意味着“语法错误,JSON 格式错误”。我猜json 命令毕竟不能使用:(
    • 效果很好。如果我只需要获取 json 字符串并删除其他任何内容怎么办?
    • @Lomse 那么在 JSON 字符串上匹配会更容易。即使用preg_match_all 而不是preg_replace。 “删除除...之外的所有内容”通常是一个标志,表明它可以以更简单的方式完成。
    【解决方案3】:

    获取一个堆栈并从头开始迭代字符串。

    for($i=0;i<count($str);$i++){
    }
    

    当你找到$str[i] == '{'时,将这个元素压入堆栈,并将起始变量初始化为$i:

    $start = $i;
    

    现在,当字符串中出现{ 或[ 时,开始压入堆栈。 如果出现] 或} 并且堆栈顶部不是{ 或],则意味着这不是正确的json。 如果不是这样,则弹出堆栈顶部并继续这样做,直到堆栈为空。

    那时你会得到$end = $i;

    这将是 json 字符串之一。 (从$start 到$end) 将此字符串推入另一个保留所有 json 的数组中。

    继续处理直到结束

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-24
      • 2016-11-05
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多