如何查找包含 JSON 数据的子字符串?

Posted

技术标签:

【中文标题】如何查找包含 JSON 数据的子字符串?【英文标题】:How to find substring that contains JSON data? 【发布时间】:2013-07-11 03:25:02 【问题描述】:

我正在尝试使用 php 在字符串中查找 JSON 字符串。

所以如果一个字符串完全是 JSON,PHP 可以这样解析它:

<?php
$json = '"a":1,"b":2,"c":3,"d":4,"e":5';

var_dump(json_decode($json));
var_dump(json_decode($json, true));

?>

但是如果我有一个类似的字符串怎么办

$str = 'I have a string that contains JSON like this : "a":1,"b":2,"c":3,"d":4,"e":5 and then string continues';

如何从中解析 JSON?

谢谢!

编辑:

感谢您的所有回答。他们真的帮助了我。我应该补充一点,就我而言,字符串将采用这种形式:

$str = 'some string and some more string [[delimiter]] json="a":1,"b":2';

而且,我不是反对者:)

【问题讨论】:

嗯,你可以使用正则表达式吗? preg_match [] 或 对? 你不应该想要它。你做错了什么。让您的 JSON 已经与任何字符串分开。 一开始为什么会有这样的字符串?用例是什么? 你唯一真正的机会是从头开始编写一个自定义 JSON 解析器,它会在字符串中查找第一个有效标记,尝试尽可能多地解码,然后悄悄地继续处理语法错误。 Regexen 不会削减它,你需要一个状态机。你真的应该避免去那里,除非你真的忍不住。 【参考方案1】:

你需要一个严肃的正则表达式,比如here,我对它进行了非常小的修改以匹配子字符串:

$str = 'I have a string [123,456] that contains JSON like this : "a":1,"b":2,"c":3,"d":4,"e":5 and then string continues';

$pcre_regex = '
  /
  (?(DEFINE)
     (?<number>   -? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)? )
     (?<boolean>   true | false | null )
     (?<string>    " ([^"\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]4 )* " )
     (?<array>     \[  (?:  (?&json)  (?: , (?&json)  )*  )?  \s* \] )
     (?<pair>      \s* (?&string) \s* : (?&json)  )
     (?<object>    \  (?:  (?&pair)  (?: , (?&pair)  )*  )?  \s* \ )
     (?<json>   \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* )
  )
  (?&json)
  /six
';

if (preg_match_all($pcre_regex, $str, $matches)) 
    print_r($matches[0]);

返回:

Array
(
    [0] =>  [123,456] 
    [1] =>  "a":1,"b":2,"c":3,"d":4,"e":5 
)

更新

您可以在表达式中添加锚点进行匹配,例如:

json=(?<expr>(?&json))\Z

【讨论】:

【参考方案2】:
preg_match('/(\.+\)/', $str, $result);
echo $result[0];

如果字符串的其余部分不包含花括号,则应该这样做。

【讨论】:

我不知道。有人正在/正在鲁莽地否决这个线程。谢谢你的回答! +1 (downvotes 但没有 cmets??) 你还应该匹配 [] 数组而不仅仅是 对象【参考方案3】:

您应该在放入字符串的 JSON 周围创建自己的特殊分隔符。如果你真的不能这样做,你可以尝试在 '"' 和 '' 之间寻找,但如果它们在你的字符串中的其他地方,它就行不通了。你可以用这个自定义函数来做到这一点:

function get_string_between($string, $start, $end)
    $string = " ".$string;
    $ini = strpos($string,$start);
    if ($ini == 0) return "";
    $ini += strlen($start);
    $len = strpos($string,$end,$ini) - $ini;
    return substr($string,$ini,$len);


$fullstring = 'I have a string that contains JSON like this : "a":1,"b":2,"c":3,"d":4,"e":5 and then string continues';
$parsed = get_string_between($fullstring, '"', '';

echo $parsed;

【讨论】:

是的,我就是这么做的。并且拆分的部分将只包含一次用于 JSON 的 ,因此您的解决方案将有效。谢谢! if ($ini == 0) return "";;那么,如果在字符串的开头找到",您会返回一个空字符串吗?这不可能! 另外,这基本上是/\".+?\/,实际上更容易阅读:) @Jack 字符串的第一个字符总是空格,看函数里面的第一行.. 这让我想到了另一点;正则表达式实际上比这段代码更容易阅读:)

以上是关于如何查找包含 JSON 数据的子字符串?的主要内容,如果未能解决你的问题,请参考以下文章

在Javascript中查找不包含/ indexOf / Regex的字符串中的子字符串

比较2个文件中的子字符串

批处理:在字符串中查找带引号的子字符串

查找适合特定区域的 UILabel 的子字符串

在c ++中使用循环查找字符串中的子字符串

如何使用后缀数组和 LCP 数组查找字符串的子字符串?