【问题标题】:Converting html headings with php regex使用 php 正则表达式转换 html 标题
【发布时间】:2014-02-16 18:32:16
【问题描述】:

我有带有 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 属性中将whitespaces 替换为underscores,我最终在$text 中得到了这个:

<p>Some random text</p>
<h2 id="This is a heading">This is a heading</h2>
<p>More text</p>

我已经尝试搜索了几个小时,但没有运气。请帮忙。

【问题讨论】:

  • 使用 html 解析器会更好。附带说明一下,如果你想在替换上运行另一个替换,你需要 preg_replace_callback。

标签: php html regex preg-replace


【解决方案1】:

使用 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);

【讨论】:

  • @mocniak:很高兴能帮上忙! (我已经更新了答案以包含更多解释 - 我希望你觉得它有用:)
猜你喜欢
  • 2012-03-11
  • 1970-01-01
  • 2011-11-20
  • 2016-04-02
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多