在字符串中查找JSON字符串

时间:2014-02-24 17:28:50

标签: php regex json

我正在寻找一种在字符串中查找JSON数据的方法。把它想象成wordpress短代码。我认为最好的方法是做一个正则表达式。我不想解析JSON,只是找到所有出现的事情。

正则表达式中是否有一种匹配括号的方法?目前,我在嵌套对象时遇到了这个问题。

演示的快速示例:

This is a funny text about stuff,
look at this product {"action":"product","options":{...}}.
More Text is to come and another JSON string
{"action":"review","options":{...}}

结果我想拥有两个JSON字符串。 谢谢!

4 个答案:

答案 0 :(得分:49)

从给定文本

中提取JSON字符串

由于您正在寻找一个简单的解决方案,您可以使用以下使用递归的正则表达式来解决匹配括号集的问题。它会递归地匹配{}之间的所有内容。

虽然,您应该注意,这并不能保证适用于所有可能的情况。它仅用作快速JSON字符串提取方法。

$pattern = '
/
\{              # { character
    (?:         # non-capturing group
        [^{}]   # anything that is not a { or }
        |       # OR
        (?R)    # recurses the entire pattern
    )*          # previous group zero or more times
\}              # } character
/x
';

preg_match_all($pattern, $text, $matches);
print_r($matches[0]);

输出:

Array
(
    [0] => {"action":"product","options":{...}}
    [1] => {"action":"review","options":{...}}
)

Regex101 Demo


验证JSON字符串

在PHP中,了解JSON字符串是否有效的唯一方法是应用json_decode()。如果解析器理解JSON字符串并且是根据定义的标准,json_decode()将创建JSON字符串的对象/数组表示。

如果您想过滤掉那些无效的JSON,那么您可以将array_filter()与回调函数一起使用:

function isValidJSON($string) {
    json_decode($string);
    return (json_last_error() == JSON_ERROR_NONE);
}

$valid_jsons_arr = array_filter($matches[0], 'isValidJSON');

Online demo

答案 1 :(得分:3)

我将添加一个*来包含嵌套对象:

{(?:[^{}]*|(?R))*}

检查Demo

答案 2 :(得分:0)

正在寻找类似正则表达式的Javascript人们。递归正则表达式(?R)不受javascript,python和其他类似语言的支持。

注意:不是一对一替换。

 \{(?:[^{}]|(?R))*\} # PCRE Supported Regex

步骤:

  1. 复制整个正则表达式并替换复制了字符串的?R 例子
  • 1级json => \{(?:[^{}]|(?R))*\} => \{(?:[^{}]|())*\}
  • 第2级json => \{(?:[^{}]|(\{(?:[^{}]|(?R))*\}))*\} => \{(?:[^{}]|(\{(?:[^{}]|())*\}))*\}
  • 级别n json => \{(?:[^{}]|(?<n times>))*\}
  1. 当决定停止某个级别时,请用空白字符串替换?R

完成。

答案 3 :(得分:0)

添加建议使用 ?R 进行递归的答案: 如果您想在正则表达式字符串中匹配其他内容,而不仅仅是 json 对象(即:一个 json 对象后跟一个字符串,例如 key: {jsonobject}),那么您只想 递归 json规则

(?<j>\{(?:[^{}]|(?&j))*\})

我在这个例子中使用了 named subpatterns。注意 ?<j>(?&j),它们定义了子模式,并分别引用了它)。 有了这个,您可以匹配以下内容作为示例:

  • 只匹配后跟“ERROR: ”的json对象:
ERROR: (?<j>\{(?:[^{}]|(?&j))*\})
ERROR: {"some": "info"}     # will match
INFO: {"some": "info"}      # won't match

参见 regex101

上的示例