Php 带“?”的图案的意外预匹配结果:&引用;

Php 带“?”的图案的意外预匹配结果:&引用;,php,regex,pcre,Php,Regex,Pcre,我试试这个式样 (?:(\d+)\/|)reports\/(\d+)-([\w-]+).html 使用此字符串(preg_匹配修饰符“Axu”) 我期望得到匹配的结果(): 但我明白了: [1] => [2] => 683868 [3] => derger-gergewrger 为什么??空值(1)在哪里,因为模式不应捕获“”: 我有两个案子: “reports/683868 derger-gerwrger.html” “757/reports/683868 derge

我试试这个式样

(?:(\d+)\/|)reports\/(\d+)-([\w-]+).html
使用此字符串(preg_匹配修饰符“Axu”)

我期望得到匹配的结果():

但我明白了:

[1] => 
[2] => 683868
[3] => derger-gergewrger
为什么??空值(1)在哪里,因为模式不应捕获“”:


我有两个案子:

  • “reports/683868 derger-gerwrger.html”
  • “757/reports/683868 derger-gerwrger.html”
  • 在第一种情况下,我需要两个捕获,但在第二种情况下,我需要三个捕获

    您可以使用:

    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
    )
    
    以及:


    (?|…)
    是一个非捕获组。此构造的每个备选方案中声明的子模式将从同一索引重新开始。

    不幸的是,我不能,因为如果存在捕获(\d+)的话,我需要它。我有两个案例:“reports/683868 derger-gergewrger.html”和“757/reports/683868 derger-gergewrger.html”,第二个案例我也需要757:(你忘了写这两个案例了吗?是的,对不起。我不知道,为什么不使用我的模式?这是必须的。如果这部分是可选的,那么当可选部分不存在时,最好先获取一个数字或空白组。是的,我想你的变体,但它看起来太难看了……好的,非常感谢你。)!关于(?|…)的解释如果捕获的数字不在字符串中,但它的存在是可选的,则相应的捕获组将包含一个空字符串。这是出于设计。好的,我现在理解了,谢谢。
    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
    )