Может ли кто-нибудь помочь мне заставить эту функцию работать? Функция должна принимать $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 .' "/>'; } ?>
Поверьте мне, что это быстрее. Я думаю, вы должны использовать эту функцию.