【问题标题】:PHP regex - weird issue with multiple group capturePHP regex - 多组捕获的奇怪问题
【发布时间】:2016-04-04 13:48:26
【问题描述】:

代码:

$pattern = '~(/(?P<lang>en|ru))?/foo(/(?P<bar>bar))?~';

preg_match($pattern, '/foo', $matches);
var_dump($matches);
/*output:
array(1) {
  [0] =>
  string(4) "/foo"
}*/
preg_match($pattern, '/foo/bar', $matches);
var_dump($matches);
/*output:
array(7) {
  [0] =>
  string(8) "/foo/bar"
  [1] =>
  string(0) ""
  'lang' =>
  string(0) ""
  [2] =>
  string(0) ""
  [3] =>
  string(4) "/bar"
  'bar' =>
  string(3) "bar"
  [4] =>
  string(3) "bar"
}*/

问题:为什么它会在第二个 preg_match 调用中捕获&lt;lang&gt;,我该如何解决?

附:我在https://www.regex101.com 上尝试了这个正则表达式,它在那里正确捕获,但在我的 PHP7 机器上,它没有。我感觉 regex101 过滤了输出。

【问题讨论】:

  • 不知道你的意思,但也许惰性匹配会有所帮助:(/(?P&lt;lang&gt;en|ru))??/foo(/(?P&lt;bar&gt;bar))?
  • 我的意思是当没有匹配时它不应该捕获lang。这没有任何意义。不,添加另一个 ? 并没有帮助。
  • 请澄清。我在您的代码演示中看到lang 是空的:'lang' =&gt; string(0) ""。未捕获任何文本。
  • ...欢迎使用 PHP :-D
  • 看看regex101:如果你在选项中启用“显示非参与组”,你会在右边看到所有的组信息。默认行为只是隐藏它们。

标签: php regex


【解决方案1】:

正如其他人所说,这就是正则表达式的工作原理。据我所知,正则表达式相当普遍。它甚至在一般编程方面也有相似之处,例如 Java 如何要求 String 返回函数来返回 String(除非它抛出错误)。

在 PHP 中,在 $matches 上使用 array_filter 删除空条目。

另外,我建议使用非捕获组(?:) 来减少混乱:

(?:/(?P&lt;lang&gt;en|ru))?/foo(?:/(?P&lt;bar&gt;bar))?

或将其拆分为 2 个正则表达式:(?:/(?P&lt;lang&gt;en|ru))/foo(?:/(?P&lt;bar&gt;bar))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2020-07-28
    • 2015-12-20
    • 2012-02-02
    • 2011-12-09
    相关资源
    最近更新 更多