在PHP中使用正则表达式提取非HTML标记

时间:2015-02-02 19:30:16

标签: php html regex html-parsing

我试图从字符串中提取非HTML标记(例如:<!This TAG>)。 我使用下面的正则表达式来提取标签:

$Tags = preg_split('/(<![^>]*[^\/]>)/i', $Content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

但问题是所有HTML评论标签(如<!-- This One -->)也将被提取。

我可以使用如下示例的技巧删除评论标签但仍会提取它们之间的任何非HTML标签!

foreach($Tags as $key => $value) {
    if(mb_substr($value, 0, 4) == '<!--')
        continue;
    $CheckTag = mb_substr($value, 0, 2);
    if($CheckTag == '<!') {
        //...
    }
}

例如:

<!--<p>some text here.</p>--> =&gt;工作

<!-- <!Tag1><!Tag2><!Tag3> --> =&gt;不行! (Tag2&amp; Tags3提取)

我正在寻找更好的正则表达式来跳过<!---->之间的整个内容,而不是任何提示。

为了更好的观点,这是原始功能:

public function extractFakeTags($Content) {
        $Tags = preg_split('/(<![^>]*[^\/]>)/i', $Content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
        $FakeTags = array();
        $Content = $Tags;
        foreach($Tags as $key => $current) {
            if(mb_substr($current, 0, 4) == '<!--')
                continue;
            $TagBegin = mb_substr($current, 0, 2);
            if($TagBegin == '<!') {
                $TagLength = mb_strlen($current);
                $TagEnd = mb_substr($current, ($TagLength-1), 1);
                if($TagEnd=='>') {
                    $TagName = mb_substr($current, 2, ($TagLength-3));
                    if (array_key_exists($TagName, $FakeTags)) {
                        array_push($FakeTags[$TagName], $key);
                    }
                    else {
                        $FakeTags[$TagName] = array($key);
                    }
                    $Content[$key] = NULL;
                }
            }
        }
        return $FakeTags;
    }

1 个答案:

答案 0 :(得分:1)

  

我正在寻找更好的正则表达式来跳过<!---->之间的整个内容

要跳过某些内容,请使用(*SKIP)(*F)。放在<!--(?s:.*?)-->(*SKIP)(*F)|之前:

/<!--(?s:.*?)-->(*SKIP)(*F)|(<![^>]*[^\/]>)/i

没有修改你的实际正则表达式。 Regex101 is good for testing也见Regex FAQ:)