PCRE: 使用PHP捕获可选模式

3
我有一个字符串需要捕获一个或两个子串(使用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}(即模式中的最终?运算符)更加贪婪(具有讽刺意味,因为作为量词修饰符时它会产生相反的效果)。
1个回答

4

在这里尝试一下

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

在Regexr上查看

我将第二组设置为非捕获组,所以你有两个捕获组,第一个包含必需的部分,第二个包含可选部分。

不能将懒惰量词与结尾处的可选部分组合使用,但如果缺少可选部分,则无需匹配必需模式后面的部分,因此将未知的垃圾包括在可选部分中即可。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接