PHP正则表达式 - 重复匹配组

Sen*_*lez 10 php regex

我有一个字符串可能看起来像这样:

$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一个多步骤方法更好; 它更具可读性,更灵活,更易于维护.

\K参考
\G参考

编辑:虽然我给出的引用是针对Perl文档的,但PHP 支持这些功能- 或者更准确地说,PCRE lib.我认为Perl文档好一点,但您也可以在PCRE手册中阅读这些内容.


cod*_*ict 7

尝试:

<?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)