Regex查找目标="_blank"链接并在关闭前添加文本</a>标签


Regex to find target="_blank" links and add text before closing </a> tag

我需要能够解析一些文本,并找到所有的实例,其中一个标签有target="_blank"....对于每个匹配,添加(例如):此链接在关闭标记之前在新窗口中打开。

例如:

:

<a href="http://any-website-on-the-internet-or-local-path" target="_blank">Go here now</a>
:后

<a href="http://any-website-on-the-internet-or-local-path" target="_blank">Go here now<span>(This link opens in a new window)</span></a>

这是一个PHP站点,所以我假设preg_replace()将是方法…我只是没有技能写正则表达式正确。

提前感谢任何人提供的帮助。

永远不要使用正则表达式来解析HTML,除非是在非常明确和受控的情况下。

请尝试使用内置解析器:
$dom = new DOMDocument();
$dom->loadHTML($your_html_source);
$xpath = new DOMXPath($dom);
$links = $xpath->query("//a[@target='_blank']");
foreach($links as $link) {
    $link->appendChild($dom->createTextNode(" (This link opens in a new window)"));
}
$output = $dom->saveHTML();

或者,如果要输出到浏览器,您可以使用CSS:

a[target='_blank']:after {
    content: ' (This link opens in a new window)';
}

这将用于锚标记替换....

$string = str_replace('<a ','<a target="_blank" ',$string);

@Kolink是对的,但这是我的RegExp版本。

$string = '<p>mess</p><a href="http://google.com.br/" target="_blank" class='"bother'">Google</a><p>mess</p>';
echo preg_replace("/('<a.*?target='"_blank'".*?>)(.*?)('<'/a'>)/miU","$1$2(This link opens in a new window)$3",$string);

完成任务:

$newText = '<span>(This link opens in a new window)</span>';
$pattern = '~<a's[^>]*?'btarget's*=(?:'s*([''"])_blank'1|_blank'b)[^>]*>[^<]*(?:<(?!/a>)[^<]*)*'K~i';
echo preg_replace($pattern, $newText, $html);

然而,这种直接字符串方法也可能取代注释的html部分,css或javascript代码中的字符串或注释,最终在javascript文字正则表达式中,这是不需要的,最坏的情况是根本不需要的。这就是为什么如果希望避免这些缺陷,就应该使用DOM方法的原因。您所要做的就是给每个链接添加一个带有所需属性的新节点:

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($html);
$xp = new DOMXPath($dom);
$nodeList = $xp->query('//a[@target="_blank"]');
foreach($nodeList as $node) {
    $newNode = dom->createElement('span', '(This link opens in a new window)');
    $node->appendChild($newNode);
}
$html = $dom->saveHTML();

最后一个选择是完全不改变html,使用css:

a[target="_blank"]::after {
    content: " (This link opens in a new window)";
    font-style: italic;
    color: red;
}

您将无法编写一个计算无限长字符串的正则表达式。我建议:

$h = explode('>', $html);

这将使你有机会像遍历其他数组一样遍历它,然后执行:

foreach($h as $k){
    if(!preg_match('/^<a href=/', $k){
        continue;
        }elseif(!preg_match(/target="_blank")/, $k){
        continue;
        }else{
        $h[$k + 1] .= '(open in new window);
        }
    }
$html = implode('>', $h);

这就是我如何处理这样一个问题。当然,我只是把这个从我的头脑中扔出来,并注意保证按原样工作,但对您的确切逻辑进行一些可能的调整,您将拥有您需要的东西。

相关文章: