【问题标题】:Match a pattern by ignoring different brackets通过忽略不同的括号来匹配模式
【发布时间】:2020-05-06 05:08:49
【问题描述】:

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

示例字符串:“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(?!\))/',因为我有三种不同的括号类型,它们必须匹配左括号和右括号。

【问题讨论】:

标签: php regex


【解决方案1】:

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

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

Regex demo

示例代码

$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 demo

【讨论】:

  • 此答案不适用于 UTF-8 字符串。此问题的解决方案是here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
  • 2022-12-07
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
相关资源
最近更新 更多