php 平衡组正则提取字符串中的 json 部分内容

正文开始

使用场景,在一个备注里面含有一串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_));

下载

正文结束

PHP接口(interface)和抽象类(abstract) phpstorm设置快捷键 ctrl+w关闭代码编辑选项卡,ctrl+open打开文件