【问题标题】:Unexpected preg_match result from pattern with "?:"来自带有“?:”的模式的意外 preg_match 结果
【发布时间】:2015-03-28 09:50:09
【问题描述】:

我试试这个模式

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

使用这个字符串(preg_match 带有修饰符“Axu”)

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/reports/683868-derger-gergewrger.html”

在第一种情况下,我需要两次捕获,但在第二种情况下,我需要三个捕获。

【问题讨论】:

  • 如果捕获的数字在字符串中不存在但它的存在是可选的,则相应的捕获组将包含一个空字符串。这是设计使然。
  • 好的,我明白了,谢谢。

标签: php regex pcre


【解决方案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
)

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

【讨论】:

  • 不幸的是我不能,因为如果它存在我需要捕获 (\d+)。我有两种情况:“reports/683868-derger-gergewrger.html”和“757/reports/683868-derger-gergewrger.html”,第二种情况我也需要757。 :(
  • 你忘了写这两个案例吗?
  • 是的,对不起。我不知道,为什么不按照我的模式工作?这是必须的。
  • 好吧,如果该部分是可选的,那么当可选部分不存在时,最好先捕获一个数字或空白组。
  • 是的,我想你的变种,但它看起来太丑了......好的,非常感谢你!并为您解释 (?|..)
猜你喜欢
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
相关资源
最近更新 更多