正则表达式删除外部链接,除了提供域相关链接PHP

时间:2016-08-24 13:59:42

标签: php regex

我希望正则表达式从我的内容中删除所有外部链接,并保留所提供域名的链接。

对于前。

$inputContent = 'Lorem Ipsum <a href="http://www.example1.com" target="_blank">http://www.example1.com</a> lorem ipsum dummy text <a href="http://www.mywebsite.com" target="_blank">http://www.mywebsite.com</a>';

预期产出:

$outputContent = 'Lorem Ipsum lorem ipsum dummy text <a href="http://www.mywebsite.com" target="_blank">http://www.mywebsite.com</a>';

尝试使用此解决方案,但它无效。

$pattern = '#<a [^>]*\bhref=([\'"])http.?://((?<!mywebsite)[^\'"])+\1 *>.*?</a>#i';  
$filteredString = preg_replace($pattern, '', $content);

3 个答案:

答案 0 :(得分:0)

这里你需要的不是正则表达式。您正在解析HTML文档,因此您应该为它选择合适的工具:DOMDocument

<?php

$html = <<< HTML
Lorem Ipsum <a href="http://www.example1.com" target="_blank">http://www.example1.com</a>
lorem ipsum dummy text
<a href="http://mywebsite.com" target="_blank">http://www.mywebsite.com</a>
HTML;


$dom = new \DOMDocument();
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED  | LIBXML_HTML_NODEFDTD);
$xpath = new \DOMXPath($dom);

$site = 'mywebsite.com';
// Query all `a` tags that don't start with your website domain name
$anchors = $xpath->query("//a[not(starts-with(@href,'http://{$site}')) and not(starts-with(@href,'http://www.{$site}'))]");

foreach ($anchors as $anchor) {
    $anchor->parentNode->removeChild($anchor);
}

echo $dom->saveHTML();

输出:

<p>Lorem Ipsum 
lorem ipsum dummy text
<a href="http://mywebsite.com" target="_blank">http://www.mywebsite.com</a></p>

答案 1 :(得分:0)

正则表达式的解决方案:

$inputContent = 'Lorem Ipsum <a href=\'http://www.example1.com\' target="_blank"><strong>http://www.example1.com</strong></a> lorem ipsum dummy text <a href="http://www.mywebsite.com" target="_blank">http://www.mywebsite.com</a>';  

function callback($matches) {
    //print_r($matches);

    if (preg_match('#^https?://(www\.)?mywebsite\.com(/.+)?$#i', $matches[1])) {
        return '<a href="' . $matches[1] . '" target="_blank">' . $matches[2] . '</a>';
    }

    //return '';
    return $matches[2]; // or you can remove only the anchor and print the text only
}

$pattern = '#<a[^>]*href=[\'"]([^\'"]*)[\'"][^>]*>(((?!<a\s).)*)</a>#i';
$filteredString = preg_replace_callback($pattern, 'callback', $inputContent);

echo $filteredString;

答案 2 :(得分:0)

  

尝试使用此解决方案,但它无法正常工作。

$pattern = '#<a [^>]*\bhref=([\'"])http.?://((?<!mywebsite)[^\'"])+\1 *>.*?</a>#i';

你很亲密。要使您的解决方案有效,请只移除一个>,i。即

  $pattern = '#<a [^>]*\bhref=([\'"])http.?://((?<!mywebsite)[^\'"])+\1 *.*?</a>#i';