簡體   English   中英

在PHP中處理格式錯誤的JSON

[英]Handling malformed JSON in PHP

我正在嘗試編寫一個php腳本來處理來自web服務的數據,該服務將“json”作為字符串傳遞。 問題是字符串不是真正的json; 這是javascript。 具體來說,雖然變量是,但不引用鍵。 示例(實際數據更長,更復雜):

{desc:'User defined payload'}

正如php手冊所述 ,json_decode()正確無法解釋此字符串。

我的問題是,如何在php中成功解釋這樣的字符串?

我能想到的唯一解決方案是編寫一些修復語法的正則表達式,但后來我遇到了兩個問題。

編輯

Hadvig建議使用Services_JSON pear模塊,並且看起來像是一個通用的解決方案。 安裝模塊后,我的代碼如下所示:

require_once 'PEAR.php';
require_once 'Services/JSON.php';

$Services_JSON = new Services_JSON();
$data = $Services_JSON->decode($malformed_json);

不幸的是,這是緩慢的。 要解釋整個字符串(約400,000個字符)需要> 36秒! 使用正則表達式修復引號然后使用json_decode花了~0.04秒。 這是我用過的東西:

// fix single quotes
$s = str_replace("'", '"', $malformed_json);

// fix unquoted keys
$valid_json = preg_replace('/([{\[,])\s*([a-zA-Z0-9_]+?):/', '$1"$2":', $s);

$data = json_decode($valid_json);

當然,如果數據包含任何引號,括號或逗號,這將會中斷。

好。 試着用這個。 http://pear.php.net/pepr/pepr-proposal-show.php?id=198我剛查看你的字符串

取決於您的數據有多復雜:

$output = "{desc:'User defined payload',asc:'whatever'}";

function json_js_php($string){

    $string = str_replace("{",'{"',$string);
    $string = str_replace(":'",'":"',$string);
    $string = str_replace("',",'","',$string);
    $string = str_replace("'}",'"}',$string);
    return $string;

}

echo json_decode(json_js_php($output))->{'desc'}; 

返回:用戶定義的有效負載

試試這個:

$jsonString = "{result:true,username:'usr000242',password:'123456',message:'Cannot send username and password to email@test.com'}";
function manualFixInvalidJSON($jsonString=''){
    $jsonString = preg_replace("/([{,])([a-zA-Z][^: ]+):/", "\$1\"$2\":", $jsonString);
    $jsonString = preg_replace("/:([a-zA-Z\'][^:]+)([,}])/", ":\"$1\"$2", $jsonString);
    $jsonString = json_decode($jsonString,true);
    function trimer($val){
        return trim(trim($val,"'"),"\"");
    }
    $jsonString = array_map('trimer', $jsonString);
    return json_encode($jsonString);
}
echo jsonString($jsonString);

使用正則表達式是不行的。 無法使用regexp正確解析JSON語法。 您將面對未來的大量錯誤。

我建議使用某種YAML解析器。 YAML與JSON向后兼容,並允許同時使用不帶引號的文字。

Symfony YAML組件對我很有用。

請記住,與json_decode相比,性能會受到json_decode因為它是本機實現的。

如果問題只是不帶引號的標識符,並且可以假設數據不包含任何大括號,那么應該這樣做:

$goodJson = preg_replace("/{\s*([a-zA-Z0-9_]+)/", '{ "$1"', $badJson);

(未經測試!)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM