2015-07-05 74 views
1

我是从一个API得到一个JSON字符串是这样的:PHP JSON字符串转义双引号里面的值?

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

未JSON使用json_decode(其输出为null)解码。

所以我想改变它的东西JSON解码,如:

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

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

为了使json_decode功能的工作,我该怎么办?

+0

如果你有可能做到这一点,你应该以正确的方式将它转义出来 – ThomasP1988

+1

如果API返回'{“key”:“foo”,“bar”:“baz”}''。是否应该转换为'{“key”:“foo”,“bar”:“baz”}(其中有两个键:'key'和'bar',值为'foo'和'baz' ),还是应该将其转换为“{”key“:”foo \“,\”bar \“:\”baz“}(1个键,'key',一个值)?目前还不清楚你想如何改变这种状况。 – Cornstalks

+1

我无法更改api,因为它不是我的。请帮我解决转义字符串的问题。 – SohrabZ

回答

0

由于昨天我试图解决这个棘手的问题,经过大量的头发拉动,我想出了这个解决方案。

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

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

分析问题:

我们知道格式化像这样的JSON键( “KeyString中” :)和JSON值( “的valueString”)

KeyString中:是除“(:”)以外的任何字符序列。

valueString:是除((,))以外的任何字符序列。

我们的目标是在valueString之内转义报价,以达到我们需要分开keyStrings和valueStrings。

  • 但我们也有这样的有效的JSON格式(“KeyString中”:数字),这将导致一个问题,因为它打破了假设说值总是以结束(”)
  • 另一个问题是具有类似于空值( “KeyString中”: “ ”)

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

  1. KeyString中JSON有(“)之前和(” :)后。
  2. JSON的valueString可以具有(: “)之前和(”)OR (:)之前,然后作为数字值(,)后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,','),',').'}'; 
} 

注:代码实现了空白。