如何查找包含 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 数据的子字符串?的主要内容,如果未能解决你的问题,请参考以下文章