PHP JSON 字符串转义双引号内的值?

PHP JSON String escape Double Quotes inside value?

我从 api 中得到一个 JSON 字符串,如下所示:

{ "title":"Example string's with "special" characters" }

无法使用 json_decode 解码 json(其输出为空)。

所以我想将其更改为 json 可解码的内容,例如:

{ "title":"Example string's with \"special\" characters" }

{ "title":"Example string's with 'special' characters" }

为了使 json_decode 功能正常工作,我应该怎么做?

从昨天开始,我一直在尝试解决这个棘手的问题,经过大量的努力,我想出了这个解决方案。

首先让我们澄清一下我们的假设。

  • json 字符串格式应该正确。
  • 键和值用双引号引起来。

分析问题:

我们知道 json 键的格式是这样的 (,"keyString":) 和 json 值是 (:"valueString",)

keyString: 是除 (:") 之外的任何字符序列。

valueString: 是除 (,).

之外的任何字符序列

我们的目标是转义 valueString 中的引号,以实现我们需要将 keyStrings 和 valueStrings 分开。

  • 但是我们也有一个有效的 json 格式,像这样 ("keyString":digit,) 这会导致问题,因为它打破了假设值总是以 (",)
  • 另一个问题是空值,例如 ("keyString":" ")

现在分析完问题我们可以说

  1. json keyString 前面有 (,"),后面有 (":)。
  2. json valueString 可以在 OR 之前和之后有 (:") 和 (",) (:) before and digit as a value then (,) after OR (:) 后跟 (" ") 然后 (,)

解决方法: 使用这个事实,代码将是

function escapeJsonValues($json_str){
  $patern = '~(?:,\s*"((?:.(?!"\s*:))+.)"\s*(?=\:))(?:\:\s*(?:(\d+)|("\s*")|(?:"((?!\s*")(?:.(?!"\s*,))+.)")))~';
  //remove { }
  $json_str = rtrim(trim(trim($json_str),'{'),'}');
  if(strlen($json_str)<5) {
    //not valid json string;
    return null;
  }
  //put , at the start nad the end of the string
  $json_str = ($json_str[strlen($json_str)-1] ===',') ?','.$json_str :','.$json_str.',';
  //strip all new lines from the string
  $json_str=preg_replace('~[\r\n\t]~','',$json_str); 

  preg_match_all($patern, $json_str, $matches);
  $json='{';
  for($i=0;$i<count($matches[0]);$i++){

        $json.='"'.$matches[1][$i].'":';
        //value is digit
        if(strlen($matches[2][$i])>0){
            $json.=$matches[2][$i].',';
        } 
        //no value
        elseif (strlen($matches[3][$i])>0) {
            $json.='"",';
        }
        //text, and now we can see if there is quotations it will be related to the text not json
        //so we can add slashes safely
        //also foreword slashes should be escaped 
        else{
            $json.='"'.str_replace(['\','"' ],['/','\"'],$matches[4][$i]).'",';
        }
  }
  return trim(rtrim($json,','),',').'}';
}

注意:代码实现了空格