3

我有一个巨大的字符串转储,其中包含常规文本和 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 /匿名/6855800

4

3 回答 3

11

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

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

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

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

于 2013-10-06T16:31:16.650 回答
1

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

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

每当您发现$str[i] == '{'将此元素推入堆栈并将开始变量初始化为$i

$start = $i;

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

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

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

并继续处理直到你到达终点

于 2013-10-06T15:56:18.667 回答
0

这是一个基于animesh seth的答案的工作代码片段。

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.
}
于 2019-11-26T19:04:53.543 回答