使用场景,在一个备注里面含有一串json文本,需要提取出来 单独加个标签括起来。
$str = '当前修改数据:{"UCName":"aaaa","firmwareModelData":"{\"type\":\"uimg\",\"value\":\"12\"}"} ';
使用单纯的{.*}语法是不能提取到完整的json的。因为json里的}会打断匹配。
语法来自之前写的js版本,完全原版翻译成php的
https://www.li6.cc/index/article/details/id/474
如果不包含json则返回原版字符串。
否则返还的结果是 3个元素的数组: 分别是 json左边的内容,json的内容,json右边的内容。
更新,支持提取多个同级别的json部分,比如
$str = 'asddsadas{"UCName":"aaaa"} bbb {"UCName":"vv"} ccc {"UCName":"adsasd"}';
一串字符串里写了3个json数据,一次可以提取完
可以提取出来
//平衡组正则提取字符串中的 json 部分内容
public static function getJsonFromStr($str) {
if(!preg_match("/{{([^\}]+)}}/", $str) && !preg_match("/{([^\}]+)}/", $str) ) return $str;
$tmpSplitTag = 'lrSplit';
$N =0;
$newStr = $str;
$zhushiLeft = '\\{';
$zhushiLeft1 = 'lrHkhZs1';
$zhushiRight = '\\}';
$zhushiRight1 = 'lrHkhZs2';
$newStr = str_replace($zhushiLeft, $zhushiLeft1, $newStr);
$newStr = str_replace($zhushiRight, $zhushiRight1, $newStr);
$newStr = preg_replace_callback("/{|}/u", function ($match) use($tmpSplitTag, &$N) {
// print_r($match[0] .'<br />');
if($match[0]==="{") {
return "[" . $tmpSplitTag . (++$N) . "]";
}
if($match[0]==="}"){
return "[/". $tmpSplitTag .($N--) ."]";
}
} , $newStr);
// print_r($newStr);
// exit;
//将首节点复原成 { }
$newStr = preg_replace("/\[". $tmpSplitTag ."1\]/u", '{', $newStr);
$newStr = preg_replace("/\[\/". $tmpSplitTag ."1\]/u", '}', $newStr);
//提取首级节点
$findFirstTagStr = function($restStr)use($zhushiLeft,$zhushiLeft1,$zhushiRight,$zhushiRight1) {
$firstTagArray = [];
preg_match("/{[^\}]+}/", $restStr, $findTag);
$findStr = $findTag[0];
$jsonStr = $findStr;
// var_dump($findTag);
if($findTag) {
$findIndex = strpos($restStr, $jsonStr);
// var_dump($findIndex);
$jsonStr = str_replace($zhushiLeft1, $zhushiLeft, $jsonStr);
$jsonStr = str_replace($zhushiRight1, $zhushiRight, $jsonStr);
if($findIndex===0) {
$firstTagArray[] = '';
$firstTagArray[] = $jsonStr;
} else {
$firstTagArray[] = substr($restStr, 0, $findIndex);
$firstTagArray[] = $jsonStr;
}
$rightStr = mb_substr($restStr, $findIndex + mb_strlen($findStr));
if(!$rightStr) {
$rightStr = '';
}
$firstTagArray[] = $rightStr;
} else {
$firstTagArray[] = $restStr;
}
return $firstTagArray;
};
$firstTagArray = $findFirstTagStr($newStr);
//复原
foreach($firstTagArray as $n_=> $str_) {
$newStr_ = $str_;
$newStr_ = preg_replace("/\[". $tmpSplitTag ."\d+\]/i", '{', $newStr_);
$newStr_ = preg_replace("/\[\/". $tmpSplitTag ."\d+\]/i", '}', $newStr_);
if($newStr_ !== $str_) {
$firstTagArray[$n_] = $newStr_;
}
}
//剩下的字符串继续查找
$endStr = $firstTagArray[2];
$endStrArray = self::getJsonFromStr($endStr);
if($endStrArray) {
unset($firstTagArray[2]);
$firstTagArray = array_merge($firstTagArray, $endStrArray);
}
foreach ($firstTagArray as $n_=>$v_) {
if(!$v_) unset($firstTagArray[$n_]);
}
return $firstTagArray;
}
$str = 'asddsadas{"UCName":"aaaa","firmwareModelData":"{\"type\":\"uimg\",\"value\":\"a\{12\{\}\{\{\"asdasd\"}} bbbb{"UCName":"aaaa","firmwareModelData":"{\"type\":\"uimg\",\"value\":\"a\{12\{\}\{\{\"asdasd\"}} ccc {"UCName":"aaaa","firmwareModelData":"{\"type\":\"uimg\",\"value\":\"a\{12\{\}\{\{\"asdasd\"}}';
$jsonData = Str::getJsonFromStr($str);
$list_ = [];
if(is_array($jsonData)) {
foreach ($jsonData as $v_) {
if(preg_match("/^\{.+\}$/", $v_)) {
$list_[] = '<div class="jsonData">'. $v_ .'</div>';
} else {
$list_[] = $v_;
}
}
}
print_r(join('', $list_));
下载