正则表达式从所有元标记中提取所有属性

时间:2011-07-17 10:35:45

标签: php regex preg-match-all meta-tags

我正在尝试从一个html页面中提取元标记,比较两个页面(实时和开发),看看他们在网站重新设计/重构后是否相同。我需要比较标题,元标签(描述,opengraph等),h1,我们的分析(Omniture),我们的广告标签(doubleclick)都是一样的。

我的问题是获取元标记 http://php.net/manual/en/function.get-meta-tags.php 仅当它们具有name =属性时才有效,与“mariano at cricava dot com”的解决方案相同。

我不想将它限制为具有某些属性,我可以假设我们所有的meta标签都有name =,或property =或http-equiv =并且适当地更改正则表达式但不能完全确定因为它是一个庞大的网站,任何随机垃圾都可以在标签中(因此这个工具是检查这些东西!)并且希望尽可能保持动态。

我有

$page = @file_get_contents('http://.../');
preg_match_all('#<meta(?:\s+?([^\=]+)\=\"(.+?)\")+?\s*?/?>#sui', $page, $matches, PREG_SET_ORDER)

但是子模式相互覆盖,所以这只会拉出最后一个attribute-name = attribute-value对

Array
(
    [0] => Array
        (
            [0] => <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            [1] => content
            [2] => text/html; charset=UTF-8
        )

    [1] => Array
        (
            [0] => <meta name="description" content="some description" />
            [1] => content
            [2] => some description
        )

    [2] => Array
        (
            [0] => <meta property="og:type" content="website" />
            [1] => content
            [2] => website
        )
...

我需要所有元标记的所有属性。我可以分两步完成这个步骤,拉出<meta ([^>]*)>的内容,然后在结果上做第二个正则表达式,但这似乎是不必要的正则表达式的力量?

3 个答案:

答案 0 :(得分:1)

  

但回到最初的问题,暂时忘记它的HTML,是吗?   无法在preg_match_all中返回重复的子模式   而不只是返回最后一场比赛?

preg_* / PCRE不可能(我也不知道任何其他正则表达式,但在Perl中你可以使用(?{ push @list, $^N }) hack)。

答案 1 :(得分:0)

 preg_match_all("<meta\\s*(?:(?:\\b(\\w|-)+\\b\\s*(?:=\\s*(?:[\"\"[^\"\"]*\"\"|'[^']*'|
   [^\"\"'<> ]|[''[^'']*''|\"[^\"]*\"|[^''\"<> ]]]+)\\s*)?)*)/?\\s*>", $content, $meta);        

试试这个

答案 2 :(得分:0)

我这样做。首先使用以下正则表达式拉出元标记

string regex = "<meta\\s(?:\"[^\"]*\"['\"]*|'[^']*'['\"]*|[^'\">])+>";

我在这里发现了正则表达式 -

RegEx match open tags except XHTML self-contained tags

然后使用另一个正则表达式拉出属性,编写起来非常简单。