正则表达式替换mailto:hrefs但忽略站点链接

时间:2011-10-10 05:45:23

标签: php regex

我需要一些帮助来调整这个正则表达式:

$content = 'more <a href="http://www.test.com">test</a> test <a href="mailto:jeff@test.com">Jeff</a> this is a <a href="http://www.test.com">test</a>';

$content = preg_replace("~<a .*?href=[\'|\"]mailto:(.*?)[\'|\"].*?>.*?</a>~", "$1", $content); 

此表达式是从mailto链接中删除html标记,只返回电子邮件(jeff@test.com)

除了上面给出的示例之外,它工作正常 - 因为在模式中的href之前允许无限数量的空格,当网站链接在mailto链接之前时,正则表达式一直向前看,直到它找到mailto:在以下链接中删除其间的所有内容。

也许修复只是将它限制在开始标记之后的两三个空格,以便看起来不那么遥远,但我想知道是否有更好的解决方案来自那些比我更了解正则表达式的人?

2 个答案:

答案 0 :(得分:6)

以下是应该使用的内容......

$dom = new DOMDocument;

$dom->loadHTML($content);

foreach($dom->getElementsByTagName('a') as $a) {
    if ($a->hasAttribute('href') 
        AND strpos($href = trim($a->getAttribute('href')), 'mailto:') === 0) {

         $textNode = $dom->createTextNode(substr($href, 7));
         $parent = $a->parentNode;
         $parent->insertBefore($textNode, $a);
         $parent->removeChild($a); 

    }   
}

CodePad

$dom->saveHTML()添加了所有HTML样板内容,例如htmlbody元素,您可以将其删除...

$html = '';
foreach($dom->getElementsByTagName('body')->item(0)->childNodes as $node) {
    $html .= $dom->saveHTML($node);
}

CodePad

答案 1 :(得分:1)

问题不是允许任何数量的空白,这将是有效的。问题是你在<a .*

中允许一个空格和任意数量的 ANY 字符

如果你解决这个问题并且只允许这样的空白

<a\s+href=[\'|\"]mailto:(.*?)[\'|\"].*?>.*?</a>
它似乎有效。

here at Regexr

但是你可能应该仔细看看alex答案(示例中为+1),因为这将是更清晰的解决方案。