【问题标题】:PCRE: Capturing optional pattern using PHPPCRE:使用 PHP 捕获可选模式
【发布时间】:2025-12-25 03:10:16
【问题描述】:

我有一个字符串,我需要从中捕获一个甚至两个子字符串(使用 PHP):

  • 第一个是强制性的
  • 第二个是可选的
  • 第一个和第二个被未知垃圾隔开
  • 第二个可能会或可能不会出现更多我不关心的垃圾

我无法让我的模式捕获第二个模式,除非我在模式字符串中强制要求它。当主题中只有第一个模式可用时,这会使模式失败。

我被难住了。这应该没那么难。

<?php

// sometimes the subject looks like this:
//$subject = 'pattern 111 -then some random junk-';
$subject = 'pattern 111 -then some random junk- pattern 222';

preg_match('/(pattern 111)(.*?)(pattern 222)?/', $subject, $matches);

print_r($matches);

?>

这是我从上面得到的:

Array
(
    [0] => pattern 111
    [1] => pattern 111
    [2] => 
)

似乎归结为如何使 {0,1}(即模式中的最后一个 ? 运算符)更加贪婪(讽刺的是,作为量词修饰符它的作用正好相反)

【问题讨论】:

    标签: php regex preg-match pcre


    【解决方案1】:

    在这里试试

    (pattern 111)(?:.*(pattern 222))?
    

    here on Regexr

    我将第二组设置为非捕获组,因此您确实有两个捕获组,第一个包含强制部分,第二个包含可选部分。

    将惰性量词与末尾的可选部分组合起来是行不通的,但是如果缺少可选部分,则无需匹配遵循强制模式的部分,因此只需将未知垃圾包含在可选部分中部分。

    【讨论】:

    • 好发现!您通常更喜欢 ?: 以防止不必要的匹配吗?我倾向于避免使用它以提高模式的可读性(而且我不介意额外的匹配)。
    • 是的,如果我不需要结果,我通常会使用非捕获组。我认为当你有 3 个组时没问题,但是当你有更多组并且只需要捕获其中的 2 个时,我认为它比重复使用更好。第 3 组和第 7 组。
    最近更新 更多