2011-07-26 6 views
9

"json"を文字列として配信するWebサービスからのデータを処理するPHPスクリプトを作成しようとしています。問題は文字列が本当にjsonではないことです。それはJavaScriptです。特に、キーは引用符で囲まれていませんが、変数はあります。例(実際のデータははるかに長く、より複雑である):PHPで不正な形式のJSONを処理する

{desc:'User defined payload'} 

php manualで説明したように、json_decode()はこの文字列を正しく解釈することができません。

私の質問は、どのように私は正常にこのような文字列をPHPで解釈できますか?

私が考えることができる唯一の解決策は、構文を修正するいくつかの正規表現を書くことですが、次に2つの問題があります。

EDIT

働いServices_JSON梨モジュールを使用してのHadvigの提案、および一般的な解決策のように見えます。モジュールをインストールすると、コードは次のようになります。

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

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

残念ながら、これはSLOWです。文字列全体(〜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); 

、データは任意の引用符、かっこ、またはカンマが含まれている場合、これは壊れます。

+0

文字列を作成するプロセスを変更することはできますか? –

+0

2つの問題がある場合は、パーザを使用する必要があるときに正規表現の使用に関する引用を知っている可能性があります) – Dan

+0

PMV:残念ながら、いいえ – Chris

答えて

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

戻り:ユーザー定義ペイロード

0

を問題は、単に引用符で囲まれていない識別子であり、データは任意の中括弧を含まないものとすることができた場合は、このそれを行う必要があります。

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

は(テストしていません!)

0

はこれを試してみてください:正規表現を使用して

$jsonString = "{result:true,username:'usr000242',password:'123456',message:'Cannot send username and password to [email protected]'}"; 
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); 
0

には、外出先ではありません。 JSON文法はregexpを使って正しく解析できません。あなたは、未来のバグのトンに自分自身を開きます。

何らかのYAMLパーサーの使用をお勧めします。 YAMLはJSONと下位互換性があり、引用符で囲まれていないリテラルも同時に使用できます。

Symfony YAML component私にとって素晴らしい仕事です。

ネイティブに実装されているため、json_decodeと比較してパフォーマンスが低下することに注意してください。

関連する問題