首页 > 解决方案 > 通过忽略不同的括号来匹配模式

问题描述

我有一个字符串,我想知道模式的第一个位置。但只有在没有用括号括起来的情况下才能找到它。

示例字符串:“ This is a (first) test with the first hit

我想知道第二个first=> 32 的位置。要匹配它,(first)必须忽略它,因为它包含在括号中。

不幸的是,我不必( )只忽略圆括号,我也必须忽略方括号[ ]和大括号{ }

我试过这个:

preg_match(
  '/^(.*?)(first)/',
  "This is a (first) test with the first hit",
  $matches
);
$result = strlen( $matches[2] );

它工作正常,但结果是第一场比赛的位置(11)。

所以我需要改变.*?.

我试图用它替换它,.(?:\(.*?\))*?希望括号内的所有字符都将被忽略。但这与括号不匹配。

而且我不能使用否定前瞻'/(?<!\()first(?!\))/',因为我有三种不同的括号类型,它们必须匹配左括号和右括号。

标签: phpregex

解决方案


您可以匹配所有 3 种您不想使用组和交替的格式,并使用(*SKIP)(*FAIL)来获取这些匹配项。first然后在单词边界之间匹配\b

(?:\(first\)|\[first]|{first})(*SKIP)(*FAIL)|\bfirst\b

正则表达式演示

示例代码

$strings = [
    "This is a (first) test with the first hit",
    "This is a (first] test with the first hit"
];

foreach ($strings as $str) {
    preg_match(
        '/(?:\(first\)|\[first]|{first})(*SKIP)(*FAIL)|\bfirst\b/',
        $str,
        $matches,
        PREG_OFFSET_CAPTURE);
    print_r($matches);
}

输出

Array
(
    [0] => Array
        (
            [0] => first
            [1] => 32
        )

)
Array
(
    [0] => Array
        (
            [0] => first
            [1] => 11
        )

)

php演示


推荐阅读