PHP preg_replace模式不以';结尾;。拉链';或';。pdf';或';。txt';

PHP preg_replace模式不以';结尾;。拉链';或';。pdf';或';。txt';,php,regex,Php,Regex,我想替换以下内容: $string='<a blah href="http://example.com/readme.zip" blah><img ><a blah href="http://example.com/readme.zqp" blah>'; $string=''; 我想在每个href中添加一个target=“\u blank”,该href不以.zip或.pdf或.txt结尾 我尝试了这样的模式:$pattern='href=“http.*(!

我想替换以下内容:

$string='<a blah href="http://example.com/readme.zip" blah><img ><a blah href="http://example.com/readme.zqp" blah>';
$string='';
我想在每个href中添加一个
target=“\u blank”
,该href不以
.zip
.pdf
.txt
结尾

我尝试了这样的模式:
$pattern='href=“http.*(!zip)”但不起作用


最好的方法是什么?

您应该真正使用PHP的内置功能来解析和处理HTML。然后您只需获取所有

请注意,由于示例HTML中没有顶级元素,因此必须在读取时添加一个(
),然后在输出时删除(使用
substr
)。如果您的实际HTML有一个顶级元素,那么您不必为此费心


如果你坚持使用正则表达式,演示中也有一个正则表达式…

你真的应该使用PHP的内置函数来解析和处理HTML。然后您只需获取所有

请注意,由于示例HTML中没有顶级元素,因此必须在读取时添加一个(
),然后在输出时删除(使用
substr
)。如果您的实际HTML有一个顶级元素,那么您不必为此费心


如果您坚持使用正则表达式,演示中也有一个正则表达式…

正如上面其他人所建议的,最好在这里使用
DOM
解析

LIBXML\u HTML\u noimpled
LIBXML\u HTML\u NODEFDTD
关闭使用
saveHTML()
时自动添加
HTML
body
元素以及doctype

您可以使用
DOMXPath
查询来收集不包含
zip
pdf
txt
引用的链接,并修改其余链接

$string = '<a blah href="http://example.com/readme.zip" blah><img ><a blah href="http://example.com/readme.zqp" blah>';
$dom = new DOMDocument();
@$dom->loadHTML($string, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);

$links = $xpath->query("//a[not(contains(@href,'zip')) and not(contains(@href,'pdf')) and not(contains(@href,'txt'))]");
foreach ($links as $link) {
    $link->setAttribute('target', '_blank');
}

print $dom->saveHTML();
$string='1!'
注意:收尾标记没有以这种方式正确放置。但是,如果在字符串开头添加一个开头
,则结尾
标记的位置不同

<div><a blah href="http://example.com/readme.zip"><img></a><a blah href="http://example.com/readme.zqp" target="_blank"></a></div>

正如上面其他人所建议的,最好在这里使用
DOM
解析

LIBXML\u HTML\u noimpled
LIBXML\u HTML\u NODEFDTD
关闭使用
saveHTML()
时自动添加
HTML
body
元素以及doctype

您可以使用
DOMXPath
查询来收集不包含
zip
pdf
txt
引用的链接,并修改其余链接

$string = '<a blah href="http://example.com/readme.zip" blah><img ><a blah href="http://example.com/readme.zqp" blah>';
$dom = new DOMDocument();
@$dom->loadHTML($string, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);

$links = $xpath->query("//a[not(contains(@href,'zip')) and not(contains(@href,'pdf')) and not(contains(@href,'txt'))]");
foreach ($links as $link) {
    $link->setAttribute('target', '_blank');
}

print $dom->saveHTML();
$string='1!'
注意:收尾标记没有以这种方式正确放置。但是,如果在字符串开头添加一个开头
,则结尾
标记的位置不同

<div><a blah href="http://example.com/readme.zip"><img></a><a blah href="http://example.com/readme.zqp" target="_blank"></a></div>

您可以使用负先行模式。试试这个

代码:
您可以使用负先行模式。试试这个

代码:
我认为您最好的选择是默认为空,并且只有在目标文件以您选择的文件格式结尾时才添加目标文件。另外,在线上有几个regex构建器可用,您至少应该尝试先创建它,如果它不起作用,再发布。投票关闭主题。也许您可以使用dom解析器,检查href是否以.zip结尾,然后添加目标。
http.*(!zip)
中的负前瞻将是真的,因为
*
将填充第一个匹配,直到字符串的结尾,而zip已经在结尾时将不在右边。我认为最好的办法是默认为空,并且只有在目标以您选择的文件格式结尾时才添加目标。另外,在线上有几个regex构建器可用,您至少应该尝试先创建它,如果它不起作用,再发布。投票关闭主题。也许您可以使用dom解析器,检查href是否以.zip结尾,然后添加目标。
http.*(!zip)
中的负前瞻将为true,因为
*
将填充第一个匹配项,直到字符串的末尾,而当zip已经在末尾时,它将不在右侧。
<div><a blah href="http://example.com/readme.zip"><img></a><a blah href="http://example.com/readme.zqp" target="_blank"></a></div>
<?php

$string='<a blah href="http://example.com/readme.zip" blah><img></a>
<a blah href="http://example.com/readme.pdf" blah><img></a>
<a blah href="http://example.com/readme.txt" blah><img></a>
<a href="http://example.com/readme.qwe" blah><img></a>
<a blah href="http://example.com/readme.zqp" blah><img></a>
<a blah href="http://example.com/readme.zip" blah><img></a>
<a blah href="http://example.com/readme.pdf" blah><img></a>
<a blah href="http://example.com/readme.txt" blah><img></a>
<a href="http://example.com/readme.qwe" blah><img></a>
<a blah href="http://example.com/readme.zqp" blah><img></a>


<!-- One line -->
<a href="http://example.com/readme.qwe" blah><img></a><a href="http://example.com/readme.qwe" blah><img></a><a blah href="http://example.com/readme.txt" blah><img></a><a blah href="http://example.com/readme.txt" blah><img></a><a blah href="http://example.com/readme.zqp" blah><img></a>';

$string = preg_replace('/<a.+?href=\"(.+?)(\.(?!zip|pdf|txt)[^\.]+?)"/i', '$0 target="_blank"', $string);

echo $string;
<a blah href="http://example.com/readme.zip" blah><img></a>
<a blah href="http://example.com/readme.pdf" blah><img></a>
<a blah href="http://example.com/readme.txt" blah><img></a>
<a href="http://example.com/readme.qwe" target="_blank" blah><img></a>
<a blah href="http://example.com/readme.zqp" target="_blank" blah><img></a>
<a blah href="http://example.com/readme.zip" blah><img></a>
<a blah href="http://example.com/readme.pdf" blah><img></a>
<a blah href="http://example.com/readme.txt" blah><img></a>
<a href="http://example.com/readme.qwe" target="_blank" blah><img></a>
<a blah href="http://example.com/readme.zqp" target="_blank" blah><img></a>


<!-- One line -->
<a href="http://example.com/readme.qwe" target="_blank" blah><img></a><a href="http://example.com/readme.qwe" target="_blank" blah><img></a><a blah href="http://example.com/readme.txt" blah><img></a><a blah href="http://example.com/readme.txt" blah><img></a><a blah href="http://example.com/readme.zqp" target="_blank" blah><img></a>