我有一个字符串可能看起来像这样:
$r = 'Filed under: <a>Group1</a>, <a>Group2</a>';
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止使用的正则表达式:
preg_match_all("/Filed under: (?:<a.*?>([\w|\d|\s]+?)<\/a>)+?/", $r, $matches);
Run Code Online (Sandbox Code Playgroud)
我希望正则表达式在内部()继续进行与+?末尾指定的匹配.但它不会这样做.::叹::
有任何想法吗.我知道必须有一种方法可以在一个正则表达式中执行此操作,而不是将其分解.
Ala*_*ore 11
只是为了好玩这里的正则表达式将与单一preg_match_all:
'%(?:Filed under:\s*+|\G</a>)[^<>]*+<a[^<>]*+>\K[^<>]*%`
Run Code Online (Sandbox Code Playgroud)
或者,以更易读的格式:
'%(?:
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'
Run Code Online (Sandbox Code Playgroud)
\G匹配下一次匹配尝试开始的位置,这通常是上一次成功匹配结束的位置(但如果前一次匹配为零长度,则会再向前碰撞一次).这意味着正则表达式不会匹配的子开始</a>,直到后它的匹配一个开始,Filed under:在至少一次.
在匹配了标记字符串或结束标记之后,将[^<>]*+<a[^<>]*+>消耗所有内容,包括下一个开始标记.然后\K欺骗开始位置,以便匹配(如果有的话)似乎在<a>标签之后开始(它就像一个积极的外观,但更灵活).最后,[^<>]+匹配标签的内容并将匹配位置添加到结束标记,以便\G匹配.
但是,正如我所说,这只是为了好玩.如果你不具备做这项工作在一个正则表达式,你就要去与像使用一个@codaddict一个多步骤方法更好; 它更具可读性,更灵活,更易于维护.
编辑:虽然我给出的引用是针对Perl文档的,但PHP 也支持这些功能- 或者更准确地说,PCRE lib.我认为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]);
}
?>
Run Code Online (Sandbox Code Playgroud)
输出:
array(4) {
[0]=>
string(6) "Group1"
[1]=>
string(6) "Group2"
[2]=>
string(6) "Group3"
[3]=>
string(6) "Group4"
}
Run Code Online (Sandbox Code Playgroud)
编辑:
由于您希望在搜索中包含字符串'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]);
}
}
Run Code Online (Sandbox Code Playgroud)