模式中出现意外的preg_match结果"?:"

时间:2015-03-28 09:50:09

标签: php regex pcre

我尝试这种模式

(?:(\d+)\/|)reports\/(\d+)-([\w-]+).html

使用此字符串(带修饰符“Axu”的preg_match)

reports/683868-derger-gergewrger.html

我希望这个匹配的结果(https://regex101.com/r/kX6yZ5/1):

[1] => 683868
[2] => derger-gergewrger

但我明白了:

[1] => 
[2] => 683868
[3] => derger-gergewrger

为什么呢?空值(1)在哪里,因为模式不应该捕获“?:”


我有两个案例:

  1. “报告/ 683868-derger-gergewrger.html”
  2. “757 /报告/ 683868-derger-gergewrger.html”
  3. 在第一种情况下,我需要两次捕获,但在第二种情况下,我需要三次捕获。

1 个答案:

答案 0 :(得分:1)

您可以使用:

preg_match('~(?:\d+/)?reports/(\d+)-([\w-]+)\.html~', 
           'reports/683868-derger-gergewrger.html', $m);
print_r($m);
Array
(
    [0] => reports/683868-derger-gergewrger.html
    [1] => 683868
    [2] => derger-gergewrger
)

编辑:您可能想要这种行为:

$s = '757/reports/683868-derger-gergewrger.html';
preg_match('~(?|(\d+)/reports/(\d+)-([\w-]+)\.html|reports/(\d+)-([\w-]+)\.html)~',
           $s, $m); print_r($m);Array
(
    [0] => 757/reports/683868-derger-gergewrger.html
    [1] => 757
    [2] => 683868
    [3] => derger-gergewrger
)

$s = 'reports/683868-derger-gergewrger.html';

preg_match('~(?|(\d+)/reports/(\d+)-([\w-]+)\.html|reports/(\d+)-([\w-]+)\.html)~',
             $s, $m); print_r($m);
Array
(
    [0] => reports/683868-derger-gergewrger.html
    [1] => 683868
    [2] => derger-gergewrger
)

(?|..)非捕获组。在此构造的每个替代项中声明的子模式将从相同的索引重新开始。