【问题标题】:remove tags <a> to a specific URL domain php [duplicate]将标签 <a> 删除到特定的 URL 域 php [重复]
【发布时间】:2019-03-05 16:13:00
【问题描述】:

这是一个不是我的脚本代码,我尝试修改它。它会搜索所有标签然后删除它们。您将如何修改代码以仅删除给定域或 url 的标签?例如,删除域标签:www.domainurl.com,删除所有标签为:

     <a href="https://www.domainurl.com/refer/google-adsense/">fsdf</a>
    <a title="Google Adsense" href="https://www.domainurl.com/refer/google-adsense/" target="_blank" rel="nofollow noopener">fgddf</a>
    <a href="https://www.domainurl.com/page/pago">domain </a>
<a title="Google Adsense" href="https://www.googlead.com/refer/google-adsense/" target="_blank" rel="nofollow noopener">googled</a>

结果如下所示:

fsdf
fgddf
domain
<a title="Google Adsense" href="https://www.googlead.com/refer/google-adsense/" target="_blank" rel="nofollow noopener">google</a>

这是代码:

if (in_array ( 'OPT_STRIP', $camp_opt )) {
                          echo '<br>Striping links ';

                        //$abcont = strip_tags ( $abcont, '<p><img><b><strong><br><iframe><embed><table><del><i><div>' );


                        preg_match_all('{<a.*?>(.*?)</a>}' , $abcont , $allLinksMatchs);


                        $allLinksTexts    = $allLinksMatchs[1];
                        $allLinksMatchs=$allLinksMatchs[0];


                        $j = 0;
                        foreach ($allLinksMatchs as $singleLink){

                            if(! stristr($singleLink, 'twitter.com'))
                            $abcont = str_replace($singleLink, $allLinksTexts[$j], $abcont);

                            $j++;
                        }
}

我试过这样做,但对我不起作用:

正则表达式:

使用 preg_match_all 在搜索中指定

 preg_match_all('{<a.*?[^>]* href="((https?:\/\/)?([\w\-])+\.{1}domainurl\.([a-z]{2,6})([\/\w\.-]*)*\/?)">(.*?)</a>}' , $abcont , $allLinksMatchs);

有什么想法吗? , 非常感谢你

【问题讨论】:

标签: php regex preg-match-all


【解决方案1】:

我选择使用 DOMDocument 类,而不是像你建议的那样尝试和parse HTML with regular expressions

function remove_domain($str, $domainsToRemove)
{
    $domainsToRemove = is_array($domainsToRemove) ? $domainsToRemove : array_slice(func_get_args(), 1);

    $dom = new DOMDocument;
    $dom->loadHTML("<div>{$str}</div>", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

    $anchors = $dom->getElementsByTagName('a');
    // Code taken and modified from: http://php.net/manual/en/domnode.replacechild.php#50500
    $i = $anchors->length - 1;
    while ($i > -1) {
        $anchor = $anchors->item($i);

        foreach ($domainsToRemove as $domain) {
            if (strpos($anchor->getAttribute('href'), $domain) !== false) {
                // $new = $dom->createElement('p', $anchor->textContent);
                $new = $dom->createTextNode($anchor->textContent);

                $anchor->parentNode->replaceChild($new, $anchor);
            }
        }

        $i--;
    }

    // Create HTML string, then remove the wrapping div.
    $html = $dom->saveHTML();
    $html = substr($html, 5, strlen($html) - (strlen('</div>') + 1) - strlen('<div>'));

    return $html;
}

然后您可以在以下示例中使用上述代码。
请注意如何将字符串作为要删除的域传递,或者传递域数组,或者利用func_get_args 并传递无限数量的参数。

$str = <<<str
     <a href="https://www.domainurl.com/refer/google-adsense/">fsdf</a>
    <a title="Google Adsense" href="https://www.domainurl.com/refer/google-adsense/" target="_blank" rel="nofollow noopener">fgddf</a>
    <a href="https://www.domainurl.com/page/pago">domain </a>
<a title="Google Adsense" href="https://www.googlead.com/refer/google-adsense/" target="_blank" rel="nofollow noopener">googled</a>
str;

// Example usage
remove_domain($str, 'domainurl.com');
remove_domain($str, 'domainurl.com', 'googlead.com');
remove_domain($str, ['domainurl.com', 'googlead.com']);

首先,我将您的字符串存储在一个变量中,但这只是为了让我可以将其用于答案;将$str 替换为您获取该代码的任何位置。

loadHTML 函数接受一个 HTML 字符串,但需要一个子元素 - 因此我将字符串包装在一个 div 中。

while 循环将遍历锚元素,然后将与指定域匹配的任何元素替换为仅锚标签的内容。
请注意,我在此行上方留下了评论,您可以使用它。这将用p 标记替换锚元素,该标记将具有display: block; 的默认样式,这意味着您的布局不会中断。但是,由于您的预期输出只是文本节点,因此我将其作为一个选项。

Live demo

【讨论】:

  • 一些想法,放置多个域,而不仅仅是一个:$domainToRemove = 'domainurl.com',google.com','domainxd.com';那么它是正确的吗?
  • @juan 我已经更新了答案,现在您可以删除多个 URL。
【解决方案2】:

怎么样:

<a.*? href=\".*www\.googlead\.com.*\">(.*?)<\/a>

这样就变成了:

preg_match_all('{<a.*? href=\".*www\.googlead\.com.*\">(.*?)<\/a>}' , $abcont , $allLinksMatchs);

这只会从www.googlead.com 中删除a 标记。

您可以查看正则表达式结果here

【讨论】:

  • 我的只是一个例子,他可以用www.domainurl.com代替它。他不想保留它,他确实想删除来自特定域的每个标签。
  • 如果将格式错误的 HTML 传递给此正则表达式,则它将与此模式匹配。例如&lt;a&gt; href="www.googlead.com"&gt;&lt;span&gt;some more stuff&lt;/span&gt;&lt;/a&gt; 将成功匹配您的表达式。
【解决方案3】:

假设您的 HTML 包含在以下变量中。

preg_replace 的用法应该是更好的选择,这里有一个函数应该可以帮到你一点:

function removeLinkTagsOfDomain($html, $domain) {
    // Escape all regex special characters
    $domain = preg_quote($domain);

    // Search for <a> tags with a href attribute containing the specified domain
    $pattern = '/<a .*href=".*' . $domain . '.*".*>(.+)<\/a>/';

    // Final replacement (should be the text node of <a> tags)
    $replacer = '$1';

    return preg_replace($pattern, '$1', $html);
}

// Usage:

$domains = [...];
$html = '...';

foreach ($domains as $d) {
    $html = removeLinkTagsOfDomain($html, $d);
}

【讨论】:

  • 你试过在同一行使用多个&lt;a&gt;标签吗?或者,如果单个&lt;a&gt; 标记分解为多行?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
  • 2021-11-03
  • 2012-12-06
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多