我想知道是否有一种优雅的方式来执行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
);
我想知道是否有更优雅/更有效的方式来做到这一点。
答案 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。