【问题标题】:Regex multiple capture groups on same pattern在同一模式上正则表达式多个捕获组
【发布时间】:2015-05-12 16:46:12
【问题描述】:

假设我有一个字符串:

12345678

我也有以下模式:

/^.*$/
/^[0-9]+$/

这两种模式都匹配字符串。我想找出两种模式都匹配字符串。我可以遍历每个模式并输入preg_match,但这太慢了。

我希望能够做这样的事情:

preg_match_all('/^(?P<pattern1>.*)|(?P<pattern2>[0-9]+)$/', $string, $matches);

然而,这会给我类似的东西:

[
    'pattern1' => '12345678',
    'pattern2' => ''
]

如您所见,pattern2 为空,因为 pattern 1 已经捕获了字符串。

我将如何编写我的preg_match_all 正则表达式,以便pattern1 和pattern2(以及任何其他模式)都有机会匹配相同的字符串?但是,如果只有所有模式都匹配,我并不遵循将返回所有模式的正则表达式规则。我希望它返回所有匹配的模式和所有不匹配的模式。

编辑

只是为了进一步澄清,

我作为示例给出的模式只是示例。

在我的实际场景中,会有未知数量的模式匹配未知字符串。

循环通过 foreach 太慢的原因是因为我将循环通过数千个字符串的几十个模式。如果可以将它们有效地组合成每个字符串的一条规则,我可以通过有多少模式来加速这部分代码。

【问题讨论】:

  • “太慢”是什么意思?你用这个干什么?
  • 这些是您正在检查的实际模式还是只是问题的一个简单示例?如果这些是实际模式,那么只需检查 strlen() 和 is_int() 的值而不是使用正则表达式,性能会更好。
  • @Ja͢ck 我将它用作高性能 url 路由器的一部分。我知道 FastRoute 存在,但即使 FastRoute 被缓存,我的解决方案平均已经快了 1.5 倍。我需要模式的部分是唯一的瓶颈,因为模式上的 foreach 循环需要太多时间。
  • @CJWurtz 这些模式只是简单的示例。实际上,模式将由库的用户定义,并且对它们可以匹配的内容没有限制。
  • 我明白你想要什么,但恐怕这不可能;这不是正则表达式匹配的设计目的。

标签: php regex preg-match-all capture regex-group


【解决方案1】:

您可以使用以下技巧:

^(?P<pattern1>(?P<pattern2>^[0-9]+$)|.*)$

由于 pattern2 在 pattern1 中并由 |.. 分隔,因此会检查每个字符是否匹配..

DEMO

【讨论】:

  • 问题在于顺序很重要;如果您切换这两种模式并创建一个字符串,例如"a12345678",您将得到错误的匹配项。
  • 如果是"a12345678",应该匹配什么?
  • 无论您提供模式的顺序如何,一个匹配项都应该是空的。
  • 交换模式不为空,即^.*$作为内部模式,\d+作为交替模式。
  • 是的.. 子集应该在内部块中.. 这就是为什么我这样写正则表达式.. 为什么要交换模式?特定问题有一定的解决方案..更改同一问题的解决方案可能并不总是有效..
猜你喜欢
  • 2018-01-19
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多