我有一个字符串,可能看起来像这样:
$r = 'Filed under: <a>Group1</a>, <a>Group2</a>';
以下是我目前使用的正则表达式:
preg_match_all("/Filed under: (?:<a.*?>([\w|\d|\s]+?)<\/a>)+?/", $r, $matches);
我希望正则表达式在()
内继续按照末尾的+?
匹配,但它却无法实现。有什么想法吗?我知道必须有一种方法可以在一个正则表达式中完成,而不是分开来做。仅供娱乐,这里有一个正则表达式,可以在单个preg_match_all
中使用:
'%(?:Filed under:\s*+|\G</a>)[^<>]*+<a[^<>]*+>\K[^<>]*%`
'%(?:
Filed under: # your sentinel string
|
\G # NEXT MATCH POSITION
</a> # an end tag
)
[^<>]*+ # some non-tag stuff
<a[^<>]*+> # an opening tag
\K # RESET MATCH START
[^<>]+ # the tag's contents
%x'
\G
匹配下一次匹配尝试开始的位置,通常是上一次成功匹配结束的地方(但如果上一次匹配长度为零,则向前移动一个)。这意味着正则表达式不会匹配以</a>
开头的子字符串,直到至少匹配了一个以Filed under:
开头的子字符串。
在匹配了哨兵字符串或结束标记之后,[^<>]*+<a[^<>]*+>
会消耗掉直到下一个起始标记的所有内容。然后\K
欺骗起始位置,使得匹配(如果有的话)看起来是在<a>
标签之后开始的(就像一个正向后行断言,但更加灵活)。最后,[^<>]+
匹配标签的内容,并将匹配位置提升到结束标记,以便\G
可以匹配。
但是,正如我所说,这只是为了好玩。如果你不必使用一个正则表达式完成任务,那么你最好使用@codaddict使用的多步方法;它更易读、更灵活和更易维护。
编辑:虽然我提供的参考资料是关于Perl文档的,但这些功能也被PHP支持,更准确地说是由PCRE库支持。我认为Perl文档更好一些,但你也可以在PCRE手册中阅读有关这些内容的信息。
尝试:
<?php
$r = 'Filed under: <a>Group1</a>, <a>Group2</a>, <a>Group3</a>, <a>Group4</a>';
if(preg_match_all("/<a.*?>([^<]*?)<\/a>/", $r, $matches)) {
var_dump($matches[1]);
}
?>
输出:
array(4) {
[0]=>
string(6) "Group1"
[1]=>
string(6) "Group2"
[2]=>
string(6) "Group3"
[3]=>
string(6) "Group4"
}
编辑:
由于您想在搜索中包含字符串“Filed under”以唯一标识匹配项,您可以尝试这样做,我不确定是否可以使用单个 preg_match 调用完成。
// Since you want to match everything after 'Filed under'
if(preg_match("/Filed under:(.*)$/", $r, $matches)) {
if(preg_match_all("/<a.*?>([^<]*?)<\/a>/", $matches[1], $matches)) {
var_dump($matches[1]);
}
}
$r = 'Filed under: <a>Group1</a>, <a>Group2</a>'
$s = explode("</a>",$r);
foreach ($s as $k){
if ($k){
$k=explode("<a>",$k);
print "$k[1]\n";
}
}
输出
$ php test.php
Group1
Group2
?
会破坏它。 - Alan Moore
\K
。有趣!关于\G
的一个小注释-您提到了“前一个匹配”,这很好,还有“下一个匹配”,这有点令人困惑(特别是当您链接的Perl示例是完全误导性的-它设置了代码中的下一个位置-这与默认行为非常不同)。简单地说-\G指的是尝试启动当前匹配的位置。</a>
始终匹配于“Filed under:”后面并不准确-它也可以匹配字符串的开头,例如</a>,<a>Group2</a>
:http://ideone.com/aTjrm。 - Kobi\G
匹配上一个匹配结束的位置,除非这些琐碎的细节与当前问题相关,否则就不必费心了。我的意思是,字符串以</a>
开头的可能性有多大呢?我对这个问题感到相当安全。 ;) - Alan Moore