[英]Converting html headings with php regex
我有带有html标记文本的字符串:
<p>Some random text</p>
<h2>This is a heading</h2>
<p>More text</p>
我想将其转换为类似的内容:
<p>Some random text</p>
<h2 id="This_is_a_heading">This is a heading</h2>
<p>More text</p>
这个简单的代码几乎可以做到:
$patterns = array('#(<h2>)(.*)(</h2>)#i');
$replace = array('<h2 id="\2">\2</h2>');
$text = preg_replace($patterns, $replace, $text);
但是我仍然不知道如何在id
属性中用underscores
替换whitespaces
,最后在$text
得到了这个:
<p>Some random text</p>
<h2 id="This is a heading">This is a heading</h2>
<p>More text</p>
我已经尝试搜索了几个小时,但是没有运气。 请帮忙。
使用HTML解析器
这是解析HTML的推荐方法。 除非您完全确定HTML字符串的格式是完全固定的,否则正则表达式处理不足,您必须使用HTML解析器。 这是使用PHP附带的DOMDocument
类的解决方案:
$dom = new DOMDocument;
$errorState = libxml_use_internal_errors(true);
$dom->loadHTML($text);
foreach ($dom->getElementsByTagName('h2') as $tag) {
$nodeValue = (string) $tag->nodeValue;
$id = str_replace(' ', '_', $nodeValue);
$tag->setAttribute('id', $id);
}
echo $dom->saveHTML();
使用正则表达式
对于简单的替换,DOM解析器可能会显得过大。 如果您不太在意结果的准确性,则可以使用正则表达式来完成任务。 请注意,如果标记之间包含其他属性或额外标签,则可能会中断此操作。
在这种情况下,您的preg_replace()
将无法工作,因为它无法修改反向引用。 使用preg_replace_callback()
代替:
$text = preg_replace_callback('#(<h2>)(.*)(</h2>)#i', function ($m) {
$id = str_replace(' ', '_',$m[2]);
return "<h2 id=\"$id\"></h2>";
}, $text);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.