我需要能够解析一些文本并查找标记具有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()将是方法...我只是没有正确编写正则表达式的技能。
提前感谢任何人提供的任何帮助。
答案 0 :(得分:7)
你永远不应该使用正则表达式来解析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)';
}
答案 1 :(得分:1)
这适用于替换锚标签....
$string = str_replace('<a ','<a target="_blank" ',$string);
答案 2 :(得分:0)
嗯@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);
答案 3 :(得分:-1)
这就是工作:
$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);
然而,这种直接字符串方法可能会替换css或javascript代码中注释的html部分,字符串或注释,并最终取代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;
}
答案 4 :(得分:-2)
您将无法编写将评估无限长字符串的正则表达式。我建议:
$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);
这就是我如何解决这个问题。当然,我只是把它扔出了我的头顶并注意保证按原样工作,但是对你的确切逻辑进行一些可能的调整,你就会得到你需要的东西。