preg_replace - 保留已在变量中替换的内容

时间:2017-09-06 10:21:52

标签: php regex

我想知道是否有一种优雅的方式来执行preg_replace,但仍保留已由preg_replace取代的内容。

例如,想象一个包含随机网站HTML的字符串。我想从该字符串中删除<head>以进行进一步处理,并仍然将<head>元素的内容保留在一个额外的变量中(例如,用于解析元标记)。

我可以想到两种可能性(不使用全局变量):

if (preg_match('%<head>(.*?)</head>%ism', $html, $matches)) {
    $html = preg_replace('%<head>(.*?)</head>%ism', '', $html);
    $head = $matches[1];
}

这个必须执行两次正则表达式,这是不理想的。

$head = '';
$html = preg_replace_callback(
        "%<head>(.*?)</head>%ism",
        function ($match) use (&$head) {
            $head .= $match[1];
            return '';
        },
        $html
);

我想知道是否有更优雅/更有效的方式来做到这一点。

1 个答案:

答案 0 :(得分:2)

您正在尝试做的事情:检索头部内容,并删除头部内容。试图将两个(相似的,但是)不同的东西合并为一个只会导致沮丧。

就个人而言,我会选择你提出的两个选项中的第一个,但是将正则表达式放入变量并重新使用它,而不是输入两次正则表达式。以后更容易更改。

但话又说回来,你考虑过使用解析器吗?

$dom = new DOMDocument();
$dom->loadHTML($html_source_here);
$headelement = $dom->getElementsByTagName('head')[0];
$headhtml = $dom->saveHTML($headelement);
$headelement->parentNode->removeChild($headelement);
$result = $dom->saveHTML();

现在您同时拥有$headelement(包含<head>...</head>包装器,包含可能包含的任何属性),以及删除了<head>的HTML。