dongsi4815 2015-07-05 18:53
浏览 461
已采纳

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

I'm getting a JSON string from an api like this :

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

which is not json decodable by using json_decode (its output is null).

so I want to change it to something json decodable like :

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

or

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

in order to make json_decode function work, what should I do ?

  • 写回答

1条回答 默认 最新

  • dongshi2141 2016-05-25 16:10
    关注

    Since yesterday I was trying to solve this tricky problem, and after a lot of hair pulling I came up with this solution.

    First let us clarify our assumptions.

    • json string should be right formated.
    • The keys and values are quoted with double quotation.

    Analyzing the problem:

    We know that json keys formated like this (,"keyString":) and json value is (:"valueString",)

    keyString: is any sequence of characters except (:").

    valueString: is any sequence of characters except (",).

    Our goal is to escape quotations inside valueString, to achive that we need to separate keyStrings and valueStrings.

    • But we have also a valid json format like this ("keyString":digit,) this will cause a problem because it breaks out assumption that says values always ended with (",)
    • Another problem is having empty values like ("keyString":" ")

    Now after analyzing the problem we can say

    1. json keyString has (,") before it and (":) after it.
    2. json valueString can have (:") before and (",) after OR (:) before and digit as a value then (,) after OR (:) followed by (" ") then (,)

    The solution: Using this facts the code will be

    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('~[
    \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,','),',').'}';
    }
    

    Note: The code realizes white spaces.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?