【问题标题】:Regex match HTML tag NOT containing another tag正则表达式匹配不包含另一个标签的 HTML 标签
【发布时间】:2011-03-31 15:35:26
【问题描述】:

我正在编写一个正则表达式查找/替换,它将在 <span> 尚不存在的文件中的每个 <a href> 中插入一个 <span>。它将允许其他标签位于<a href> 中,例如<img><b> 等。

目前我有这个正则表达式:
查找:(<a[^>]+?style=".*?color:#(\w{6}).*?".*?>)(.+?)(<\/a>)
替换:'$1<span style="color:#$2;">$3</span>$4'

它工作得很好,除非我在同一个文件上运行它,它会在 <span> 内插入一个 <span> 并且它会变得混乱。

目标示例:

我们希望它忽略这个:
<a href="http://mywebiste.com/link1.html" target="_blank" style="color:#bfbcba; text-decoration:underline;"><span style="color:#bfbcba;">Howdy</span></a>

但不是这个:
<a href="http://mywebiste.com/link1.html" target="_blank" style="color:#bfbcba; text-decoration:underline;">Howdy</a>

或者这个:
<a href="http://mywebiste.com/link1.html" target="_blank" style="color:#bfbcba; text-decoration:underline;"><img src="myimg.gif" />Howdy</a>

--编辑--

使用 cmets 中建议的 PHP DOM 库,这是我目前所拥有的:

$doc = new DOMDocument();
$doc->loadHTML($input);
$tags = $doc->getElementsByTagName('a');
foreach ($tags as $tag) {
    $spancount = $tag->getElementsByTagName("span")->length;
    if($spancount == 0){
        $element = $doc->createElement('span');
        $tag->appendChild($element);
    }
}

echo $doc->saveHTML();`

目前它会检测锚内部是否有跨度,如果有,它将在锚内部附加一个跨度,但是,我还没有弄清楚如何获取锚内部的原始内容跨度。

【问题讨论】:

  • 用什么语言?可能是 Perl、PHP 或 Javascript?
  • 不要使用正则表达式来匹配 HTML。使用 HTML 解析器。
  • 使用正则表达式解析 XML (HTML) 是个坏主意。使用 HTML 解析器。
  • 这完美回答了你的问题:stackoverflow.com/a/1732454/13365

标签: php html regex dom


【解决方案1】:

不要为此使用正则表达式,它不适合 HTML。

使用 DOM 库和getElementsByTagName('a'),然后使用length 属性遍历每个锚点并查看它是否包含带有getElementsByTagName('span') 的子跨度元素。如果没有,appendChild 或将锚节点的firstChild 分配给使用document.createElement('span') 创建的新跨度。

编辑:至于抓取anchor的内部html,如果里面有很多节点,试试这个:

<?php
function innerHTML($node){
  $doc = new DOMDocument();
  foreach ($node->childNodes as $child)
    $doc->appendChild($doc->importNode($child, true));

  return $doc->saveHTML();
}

$html = innerHTML( $anchorRef );

这也可能对您有所帮助:Change innerHTML of a php DOMElement

【讨论】:

  • 完整的 ack、正则表达式和 html = 错误。虽然为了使用 lynx 的 ppl,我可能会使用 html 解析器甚至 simplexml 而不是 javascript。
  • 感谢 DOM 的建议。我已经开始使用 PHP DOM(第一次!),我花了很长时间来整理如何获取元素的内容:&lt;a href="link.html"&gt;&lt;b&gt;my link&lt;/b&gt;&lt;/a&gt; 在这种情况下为&lt;b&gt;my link&lt;/b&gt;,然后将其包装在一个跨度中.我在创建新的 span 元素并附加它时没有问题,但是在 &lt;span&gt; 中获取原始内容一直困扰着我。
  • 好吧,如果您在原始答案中发布您的尝试,我(和其他人)会更容易提供帮助。
  • 好电话。请参阅编辑后的帖子。感谢您的帮助!
  • 上述innerHTML() 函数的一个问题是它返回一个字符串,当我将锚的nodeValue 设置为返回的字符串时,HTML 被转义为:@987654334 @ 我的foreach 循环的主体现在看起来像这样:` $element = $doc->createElement('span'); $content = innerHTML($tag); $element->setAttribute('style','color:#ffffff;'); $element->nodeValue = $内容; $tag->nodeValue = ""; //清除节点 $tag->appendChild($element);`
猜你喜欢
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
  • 2015-03-31
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多