2015-07-05 73 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,','),',').'}'; 
} 

注:代碼實現了空白。