在PHP中处理格式错误的JSON

时间:2011-07-26 21:00:25

标签: php json

我正在尝试编写一个php脚本来处理来自web服务的数据,该服务将“json”作为字符串传递。问题是字符串不是真正的json;这是javascript。具体来说,虽然变量是,但不引用键。示例(实际数据更长,更复杂):

{desc:'User defined payload'}

php manual所述,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);

当然,如果数据包含任何引号,括号或逗号,则会中断。

5 个答案:

答案 0 :(得分:2)

确定。试着用这个。 http://pear.php.net/pepr/pepr-proposal-show.php?id=198我只是查看你的字符串

答案 1 :(得分:1)

取决于您的数据有多复杂:

$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'}; 

返回:用户定义的有效负载

答案 2 :(得分:0)

如果问题只是不带引号的标识符,并且可以假设数据不包含任何大括号,那么应该这样做:

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

(未经测试!)

答案 3 :(得分:0)

试试这个:

$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);

答案 4 :(得分:0)

使用regexp是不行的。无法使用regexp正确解析JSON语法。你将面对未来的大量错误。

我建议使用某种YAML解析器。 YAML与JSON向后兼容,并允许同时使用不带引号的文字。

Symfony YAML component对我很有用。

请记住,与json_decode相比,性能会受到影响,因为它是本机实现的。