【问题标题】:check for a JSON string inside of a larger string in PHP在 PHP 中检查较大字符串中的 JSON 字符串
【发布时间】:2019-01-09 09:37:08
【问题描述】:

这里是一个日志文件条目的例子:

[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}

{"api_url":"https:\/\/api.wordpress.... 部分是有效的 JSON,但显然整个字符串本身(日志条目行)不是。我正在用一种方法来本质上拉出 JSON 而不会弄乱字符串的任何其他部分。

【问题讨论】:

  • 看起来你可以剪掉第一个大括号之前的所有内容,以及最后一个大括号之后的所有内容。
  • JSON 是在 Details: 之后出现的。所以这是一个提示。
  • 这是一个示例。它不会总是在前面有“细节”(或其他任何东西)

标签: php json regex


【解决方案1】:

使用preg_match_all 查找所有 JSON 并将其存储到一个数组中,如下所示:

$text = '[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}';

preg_match_all('/\{(?:[^{}]|(?R))*\}/x', $text, $matches);

echo '<pre>';
print_r($matches[0]);

这会产生:

Array
(
    [0] => {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}
)

您可以阅读更多内容: Extracting the JSON string from given text

或者,如果您想要相反并删除 JSON 并保留字符串,那么您可以使用 preg_replace 来执行此操作:

$text = '[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}';

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

echo $cleantext;

来自PHP: How to extract JSON strings out of a string dump的信用

这会产生:

[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details:

【讨论】:

    【解决方案2】:

    您可以尝试获取 json 对象的开头和结尾并对其进行解码。如果没有 json 解码错误,那么你很好。这里假设字符 {} 仅在 json 正文中使用。

    function checkIfStringHasValidJson($string)
    {
        $start = strpos($string, '{');
        $end = strrpos($string, '}');
        $json = substr($string, $start, $end);
        json_decode($json);
        return json_last_error() === JSON_ERROR_NONE;
    }
    

    【讨论】:

    • 想说这也有效,但 preg_match_all 会得到所有这些(如果存在多个)
    • @Norcross 有道理,我假设只有一个物体,并且故意保持它的光亮。很高兴您有解决方案!
    【解决方案3】:

    只需从字符串中删除所有内容,包括“详细信息:”的给定子字符串:

    $s = '[22-Aug-2017 16:19:58 America/New_York] WP_Community_Events::maybe_log_events_response: Valid response received. Details: {"api_url":"https:\/\/api.wordpress.org\/events\/1.0\/","request_args":{"body":{"number":5,"ip":"192.168.99.0","locale":"en_GB","timezone":"America\/New_York"}},"response_code":200,"response_body":{"location":{"ip":"47.197.97.47"},"events":"5 events trimmed."}}';
    $out = str_replace('Details: ', '', strstr($s, 'Details:'));
    echo var_export(json_decode($out));
    

    【讨论】:

      猜你喜欢
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 2014-10-22
      • 2012-02-15
      相关资源
      最近更新 更多