由於昨天我試圖解決這個棘手的問題,經過大量的頭髮拉動,我想出了這個解決方案。
首先讓我們澄清我們的假設。
- json字符串應該是正確的格式。
- 鍵和值用雙引號引起來。
分析問題:
我們知道格式化像這樣的JSON鍵( 「KeyString中」 :)和JSON值( 「的valueString」)
KeyString中:是除「(:」)以外的任何字符序列。
valueString:是除((,))以外的任何字符序列。
我們的目標是在valueString之內轉義報價,以達到我們需要分開keyStrings和valueStrings。
- 但我們也有這樣的有效的JSON格式(「KeyString中」:數字),這將導致一個問題,因爲它打破了假設說值總是以結束(」)
- 另一個問題是具有類似於空值( 「KeyString中」: 「 」)
現在分析這個問題後,我們可以說
- KeyString中JSON有(「)之前和(」 :)後。
- 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,','),',').'}';
}
注:代碼實現了空白。
如果你有可能做到這一點,你應該以正確的方式將它轉義出來 – ThomasP1988
如果API返回'{「key」:「foo」,「bar」:「baz」}''。是否應該轉換爲'{「key」:「foo」,「bar」:「baz」}(其中有兩個鍵:'key'和'bar',值爲'foo'和'baz' ),還是應該將其轉換爲「{」key「:」foo \「,\」bar \「:\」baz「}(1個鍵,'key',一個值)?目前還不清楚你想如何改變這種狀況。 – Cornstalks
我無法更改api,因爲它不是我的。請幫我解決轉義字符串的問題。 – SohrabZ