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

时间:2015-07-05 18:53:07

标签: php json string escaping double-quotes

我从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功能正常工作,我该怎么办?

1 个答案:

答案 0 :(得分:0)

从昨天起我就试图解决这个棘手的问题,经过大量的拔毛后,我想出了这个解决方案。

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

  • json string应该是正确格式化的。
  • 键和值以双引号引用。

分析问题:

我们知道json键形成如下(" keyString" :)和json值是(:" valueString",)

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

valueString :除了(",)之外的任何字符序列。

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

  • 但是我们也有一个像这样的有效json格式(" keyString":digit),这会引起一个问题,因为它突破了所说的值总是以(",)结束的假设/ LI>
  • 另一个问题是空值如(" keyString":"")

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

  1. json keyString在它之前有(,"),在它之后有(" :)。
  2. json valueString可以在(>")之前和(")之后 OR (:)之前和数字作为值然后(,)在 OR 之后 (:)后跟("")然后(,)
  3. 解决方案: 使用这个事实代码将是

    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,','),',').'}';
    }
    

    注意:代码实现了空格。