Чтение PHP недопустимым json с json_decode ();

У меня есть недопустимые внешние данные json, без двойных кавычек вокруг имен.

Пример:

{ data: [ { idx: 0, id: "0", url: "http://247wallst.com/", a: [ { t: "Title", u: "http://247wallst.com/2012/07/30/", sp: "About" } ], doc_id: "9386093612452939480" }, { idx: 1, id: "-1" } ], results_per_page: 10, total_number_of_news: 76, news_per_month: [20, 0, 8, 1, 1, 2, 0, 2, 1, 0, 0, 1, 1, 0, 5, 1, 1, 1, 0, 2, 5, 16, 7, 1], result_start_num: 2, result_end_num: 2, result_total_articles: 76 } 

Как вы видите, многие имена, такие как данные, idx, id, url и другие, не имеют двойных кавычек, поэтому это делает этот json недействительным. Как я могу сделать этот внешний json действительным? Я уже попробовал str_replace, заменив '{' на '{"' и ':' to '":' добавление двойных кавычек вокруг некотируемых имен, но это испортило некоторые уже двойные кавычки.

Как я могу сделать этот json действительным, чтобы я мог читать эти данные с помощью PHP json_decode? Я не очень хорошо знаком с preg_replace ..

Действительный json будет выглядеть так:

 { "data": [ { "idx": 0, "id": "0", "url": "http://247wallst.com/", "a": [ { "t": "Title", "u": "http://247wallst.com/2012/07/30/", "sp": "About" } ], "doc_id": "9386093612452939480" }, { "idx": 1, "id": "-1" } ], "results_per_page": 10, "total_number_of_news": 76, "news_per_month": [20, 0, 8, 1, 1, 2, 0, 2, 1, 0, 0, 1, 1, 0, 5, 1, 1, 1, 0, 2, 5, 16, 7, 1], "result_start_num": 2, "result_end_num": 2, "result_total_articles": 76 } 

Пожалуйста, предложите мне функцию php preg_replace.

Источник данных: http://www.google.com/finance/company_news?q=aapl&output=json&start=1&num=1

С помощью preg_replace вы можете:

 json_decode(preg_replace('#(?<pre>\{|\[|,)\s*(?<key>(?:\w|_)+)\s*:#im', '$1"$2":', $in)); 

Поскольку приведенный выше пример не будет работать с реальными данными (планы сражений редко выживают при первом контакте с врагом), мой второй прием:

 $infile = 'http://www.google.com/finance/company_news?q=aapl&output=json&start=1&num=1'; // first, get rid of the \x26 and other encoded bytes. $in = preg_replace_callback('/\\\x([0-9A-F]{2})/i', function($match){ return chr(intval($match[1], 16)); }, file_get_contents($infile)); $out = $in; // find key candidates preg_match_all('#(?<=\{|\[|,)\s*(?<key>(?:\w|_)+?)\s*:#im', $in, $m, PREG_OFFSET_CAPTURE); $replaces_so_far = 0; // check each candidate if its in a quoted string or not foreach ($m['key'] as $match) { $position = $match[1] + ($replaces_so_far * 2); // every time you expand one key, offsets need to be shifted with 2 (for the two " chars) $key = $match[0]; $quotes_before = preg_match_all('/(?<!\\\)"/', substr($out, 0, $position), $m2); if ($quotes_before % 2) { // not even number of not-escaped quotes, we are in quotes, ignore candidate continue; } $out = substr_replace($out, '"'.$key.'"', $position, strlen($key)); ++$replaces_so_far; } var_export(json_decode($out, true)); 

Но так как Google предлагает эти данные в RSS-канале, я бы порекомендовал вам использовать его, если он работает для вашего usecase, это просто для удовольствия (-:

Каналы JSON от Google всегда, похоже, страдают от проблем, отформатированных некорректно в какой-то форме или форме. Если вы переключите канал на RSS, вы можете легко преобразовать его в массив или JSON из массива.

 <?php $contents = file_get_contents('http://www.google.com/finance/company_news?q=aapl&output=rss&start=1&num=1'); // Convert the RSS to an array (probably just use this) $arr = simplexml_load_string($contents); // Or if you specifically want JSON $json = json_encode($arr); // And back to an array print_r(json_decode($json));