在PHP中处理格式错误的JSON

在PHP中处理格式错误的JSON,php,json,Php,Json,我正在尝试编写一个php脚本,该脚本处理来自以字符串形式提供“json”的Web服务的数据。问题是字符串不是真正的json;这是javascript。具体来说,键不被引用,尽管变量被引用。示例(实际数据更长、更复杂): 如所述,json_decode()无法正确解释此字符串 我的问题是,如何在php中成功地解释这样的字符串 我能想到的唯一解决方案是编写一些正则表达式来修复语法,但这样我就有两个问题了 编辑 Hadvig关于使用Services_JSON pear模块的建议奏效了,看起来是一个通用

我正在尝试编写一个php脚本,该脚本处理来自以字符串形式提供“json”的Web服务的数据。问题是字符串不是真正的json;这是javascript。具体来说,键不被引用,尽管变量被引用。示例(实际数据更长、更复杂):

如所述,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);
不幸的是,这是缓慢的。解释整个字符串(~400000个字符)需要超过36秒!使用正则表达式修复引号,然后使用json_解码需要约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);

当然,如果数据包含任何引号、方括号或逗号,这将中断。

取决于数据的复杂程度:

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

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

如果问题只是未加引号的标识符,并且可以假定数据不包含任何花括号,则应该这样做:

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

正常。试着用这个。我只是检查你的字符串

试试这个:

$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是不可能的。无法使用regexp正确解析JSON语法。你将对未来的大量bug敞开心扉

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

这对我很有用


请记住,与
json_decode
相比,将有一个性能损失,因为它是本机实现的。

您可以更改创建字符串的任何进程吗?如果您知道这两个问题,那么您可能知道在应该使用解析器时使用正则表达式;)乔:我很想知道一个能处理这个问题的解析器。你能给我指一个吗?给那些能修改格式的人安装窃听器!
$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);