2

名前を二重引用符で囲まずに、無効な外部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
}

ご覧のとおり、data、idx、id、urlなどの多くの名前は二重引用符で囲まれていないため、このjsonは無効になります。この外部JSONを有効にするにはどうすればよいですか?私はすでにstr_replaceを試し、'{'を'{"'に、':'を'":'に置き換え、引用符で囲まれていない名前の前後に二重引用符を追加しましたが、これはすでに二重引用符で囲まれた変数を台無しにします。

この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
}

phppreg_replace関数を提案してください。

データソース: http ://www.google.com/finance/company_news?q = aapl&output = json&start = 1&num = 1

4

2 に答える 2

4

Google からの JSON フィードは、常に問題に悩まされているようです。何らかの形や形式でフォーマットが正しくありません。フィードを 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));
于 2012-07-30T21:01:16.047 に答える
4

あなたpreg_replaceができること:

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

上記の例は実際のデータでは機能しないため (戦闘計画が敵との最初の接触で生き残ることはめったにありません)、私の 2 番目の例を次に示します。

$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 フィードでこのデータを提供しているので、それがあなたのユースケースで機能する場合は、それを使用することをお勧めします。これはただの楽しみです (-:

于 2012-07-30T20:43:57.680 に答える