PHP-функция для замены тега HTML (например, мета-описание) с использованием preg_replace

Может ли кто-нибудь помочь мне заставить эту функцию работать? Функция должна принимать $HTMLstr – целую страницу HTML, заполненную в строку, которая уже содержит мета-описание в виде:

 <meta name="description" content="This will be replaced"/> 

наряду с $content который является строкой, которая должна заменить «Это будет заменено». Я думал, что я близок с этой функцией, но это не работает.

 function HTML_set_meta_description ($HTMLstr, $content) { $newHTML = preg_replace('/<meta name="description"(.*)"\/>/is', "<meta name=\"description\" content=\"$content\"/>", $HTMLstr); return ($newHTML); } 

Спасибо за любую помощь!

Редактировать: вот рабочая функция.

 function HTML_set_meta_description ($HTMLstr, $content) { // assumes meta format is exactly <meta name="description" content="This will be replaced"/> $newHTML = preg_replace('/<meta name="description" content="(.*)"\/>/i','<meta name="description" content="' . $content . '" />', $HTMLstr); return ($newHTML); 

}

Использование DOMDocument рекомендуется как уже ответ, однако, если вы боретесь с регулярным выражением, я могу помочь вам. Вместо этого вы можете попробовать:

 return preg_replace('/<meta name="description" content="(.*)"\/>/i','<meta name="description" content="Something replaced" />', $HTMLstr); 

Если вы не знаете, что <meta> будет предоставлен в согласованном формате (который трудно узнать, если вы фактически не контролируете HTML), вам будет очень сложно построить рабочее регулярное выражение. Возьмем следующие примеры:

 <meta content="content" name="description"> <meta content = 'content' name = 'description' /> <meta name= 'description' content ="content"/> 

Все они действительны, но регулярное выражение, которое будет обрабатывать их, будет очень сложным. Что-то вроде:

 @<meta\s+name\s*=\s*('|")description\1\s+content\s*('|")(.*?)\2\s+/?>@ 

… и это даже не учитывает атрибуты, находящиеся в другом порядке. Возможно, было и то, о чем я даже не думал.

С другой стороны, использование парсера, такого как DOMDocument, может быть очень дорогостоящим, особенно если ваш HTML большой. Если вы можете зависеть от согласованного формата для <meta> который хотите использовать .*? вместо .* для захвата содержимого. .*? делает поиск неохотой, поэтому он останавливается при первой цитате, а не в последней, – вероятно, в тексте HTML будет много других котировок.

 $dom = new DOMDocument; $dom->loadHTML($HTMLstr); foreach ($dom->getElementsByTagName("meta") as $tag) { if (stripos($tag->getAttribute("name"), "description") !== false) { $tag->setAttribute("content", $content); } } return $dom->saveHTML(); 

Я знаю, что вы спросили preg_replace и им поздно ответить, но посмотрите на это, это то, что вы ищете …

 <?php function meta_desc( $content = null ){ $desc = 'This will be replaced '; if( $content ){ $desc = $content; } return '<meta name="description" content=" '. $desc .' "/>'; } ?> 

Поверьте мне, что это быстрее. Я думаю, вы должны использовать эту функцию.