PHP

2011-07-26 9 views
9

में विकृत JSON को संभालने में मैं एक php स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो एक webservice से डेटा को संभालता है जो स्ट्रिंग के रूप में "json" प्रदान करता है। समस्या यह है कि स्ट्रिंग वास्तव में जेसन नहीं है; यह जावास्क्रिप्ट है। विशेष रूप से, चाबियाँ उद्धृत नहीं की जाती हैं, हालांकि चर हैं। उदाहरण (वास्तविक डेटा बहुत लंबे समय तक और अधिक जटिल है): php manual ने वर्णन किया हैPHP

{desc:'User defined payload'} 

, json_decode() सही ढंग से इस स्ट्रिंग व्याख्या करने के लिए विफल रहता है।

मेरा सवाल है, मैं php में इस तरह की स्ट्रिंग को सफलतापूर्वक कैसे समझ सकता हूं?

एकमात्र समाधान जो मैं सोच सकता हूं वह सिंटैक्स को ठीक करने वाले कुछ नियमित अभिव्यक्तियों को लिखना है, लेकिन फिर मुझे दो समस्याएं होती हैं।

संपादित

Services_JSON नाशपाती मॉड्यूल का उपयोग करने का Hadvig के सुझाव काम किया, और एक सामान्य समाधान की तरह दिखता है। एक बार जब मैंने मॉड्यूल स्थापित किया, तो मेरा कोड इस तरह दिखता था:

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); 
बेशक

, अगर डेटा किसी भी उद्धरण, कोष्ठक, या अल्पविराम शामिल इस टूट जाएगा।

+0

क्या आप स्ट्रिंग बनाने वाली प्रक्रिया को बदल सकते हैं? –

+0

यदि आप दो-समस्या वाले उद्धरणों को जानते हैं, तो आपको शायद पार्सर का उपयोग करने पर नियमित अभिव्यक्तियों का उपयोग करने के बारे में उद्धरण पता हो;) – Dan

+0

पीएमवी: दुर्भाग्य से, – 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

regexp का उपयोग करते हुए नो-जाना है। JSON व्याकरण regexp का उपयोग कर सही ढंग से पार्स नहीं किया जा सकता है। आप खुद को भविष्य की बग के एक टन में खुलेंगे।

मैं किसी प्रकार का वाईएएमएल पार्सर का उपयोग करने की सलाह देता हूं। वाईएएमएल जेएसओएन के साथ पीछे-संगत है और एक ही समय में बिना छेड़छाड़ की अनुमति देता है।

Symfony YAML component मेरे लिए बहुत अच्छा काम किया।

और याद रखें कि json_decode की तुलना में प्रदर्शन दंड होगा क्योंकि यह मूल रूप से कार्यान्वित किया गया है।

संबंधित मुद्दे