【问题标题】:PHP - file_get_contents get JSON with regex, but can't JSON decode (got JSON_ERROR_SYNTAX)PHP - file_get_contents 使用正则表达式获取 JSON,但无法 JSON 解码(获取 JSON_ERROR_SYNTAX)
【发布时间】:2016-02-23 16:47:52
【问题描述】:

我尝试解析此页面:http://fr.hearthhead.com/cards 以获取 hearthstoneCards JS 变量。 所以我做了这样的事情:

$url = 'http://fr.hearthhead.com/cards';
$content = file_get_contents($url);
preg_match('#var hearthstoneCards = (.*)}]\;#Us', $content, $out);
$out = $out[1].'}]';
$tab_id_card = json_decode($out,true);

我尝试了我能找到的所有技巧(修剪、stripslashes、预置 BOM 和其他东西,在 json_decode 和许多其他东西上放置标志),但我没有得到这个工作。

如果我对 $out 变量进行 file_put_contents 并与真实源进行比较,则它是相同的(相同的长度)。如果我将字符串放在 JS 控制台上,我会得到数据。但是 PHP 不想解析这个 var :(

有人有想法吗? :)

【问题讨论】:

  • 我这里没有JSON_ERROR_SYNTAXjson_decode() 只返回NULL。您确定收到此错误吗?
  • 通过检查 json_last_error() 导致它返回 NULL,感谢您的测试! :)
  • 并非所有属性名称都用双引号括起来,例如{ ...., popularity:2 }。虽然在 javascript 中有效,但它不在 JSON 中,因此会出现解析错误。 $out = str_replace('popularity:', '"popularity":', $out); 目前将是一个不稳定的快速修复......
  • 何没有看到@VolkerK 所以现在我唯一的方法是构建一个正则表达式来转换它,也许它甚至不可能,这很可悲:-/
  • 该死的,我刚找到一样的!不过我会给你写一个很好的答案:)

标签: javascript php json regex


【解决方案1】:

问题是您假设代码是 JSON,而实际上它是完全成熟的 JavaScript。在该代码中,属性名称 popularity 出现了许多未加引号的重复,这是很好的 JavaScript,但无效的 JSON。

我尝试构建一个正则表达式来修复任何未引用的属性名称。问题是,这是不可行的。就我而言,值中的任何冒号都破坏了我的正则表达式。

无需编写解析器来修复此类不符合项或调用 JS 解释器(这将需要诸如 V8Js 之类的外部依赖项),我认为您现在可以解决此特定情况:

$url = 'http://fr.hearthhead.com/cards';
$content = file_get_contents($url);
preg_match('#var hearthstoneCards = (.*)}]\;#Us', $content, $out);
$out = str_replace('popularity', '"popularity"', $out);
$out = $out[1].'}]';
$tab_id_card = json_decode($out,true);

如果您担心将来引入新的未引用属性,您可以检查 $tab_id_card 以获取 NULL 并在您经常检查的地方记录错误,甚至以某种方式为自己发出通知。虽然我会这样做,但我想说这不太可能发生,因为所有其他属性都被正确引用了。

【讨论】:

  • 从技术上讲,您不需要“编写 JSON 解释器”,这就是 json_decode 的用途。你需要的是一个 JS object literal 解释器,为此你可以使用v8js.
  • @dcoder 我完全掩盖了这个字符串最初是 不是 JSON,而只是 JS 的事实。我会相应地更新我的答案。
  • 谢谢你们,你们太棒了! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-16
相关资源
最近更新 更多