获取所有没有特定前缀组的单词

时间:2017-04-26 10:00:24

标签: php regex

我有一个以下形式的字符串

$string = "This is {test} for [a]{test2} for {test3}.";

我希望得到所有不带方括号前缀的花括号。因此,在上面的字符串中,我想获得{test}{test3},但不是[a]{test2}

我在答案https://stackoverflow.com/a/977294/2311074中发现,这可能是负面的前瞻。所以我试过

  $regex      = '/(?:(?!\[[^\}]+\])\{[^\}]+\})/';
  echo preg_match_all($regex, $string, $matches) . '<br>';
  print_r($matches);

但这仍然给了我三个大括号。

  

3

     

数组([0] =&gt;数组([0] =&gt; {test} [1] =&gt; {test2} [2] =&gt; {test3})   )

为什么这不起作用?

2 个答案:

答案 0 :(得分:2)

如果你确定打开花括号后面只会有一对方括号(平衡),那么负面的后视将会完成这项任务:

{{1}}

Live demo

答案 1 :(得分:1)

你的正则表达式失败的原因是它匹配任何{(后跟1 +非} s然后是})如果它没有启动模式序列在负面预测中,[,除了}之外的1 +字符,然后是](并且它始终为真,因此,您将所有{...}个子字符串作为结果)。

使用(*SKIP)(*FAIL) technique

\[[^]]*]\{[^}]+}(*SKIP)(*F)|\{[^\}]+}

请参阅regex demo

<强>详情:

  • \[[^]]*]\{[^}]+}(*SKIP)(*F) - 匹配
    • \[ - [
    • [^]]* - 除]
    • 以外的0个字符
    • ]\{ - ]{ substring
    • [^}]+ - 除]以外的1个字符
    • } - 文字}
    • (*SKIP)(*F) - PCRE动词丢弃目前为止匹配的文本并强制引擎继续从当前位置寻找下一个匹配(就像发生了匹配一样)
  • | - 或
  • \{[^\}]+}
    • \{ - {
    • [^\}]+ - 除}
    • 以外的1个字符
    • } - 文字}

请参阅PHP demo

$string = "This is {test} for [a]{test2} for {test3}.";
$regex      = '/\[[^]]*]\{[^}]+}(*SKIP)(*F)|\{[^}]+}/';
echo preg_match_all($regex, $string, $matches) . "\n";
print_r($matches[0]);

输出:

2
Array
(
    [0] => {test}
    [1] => {test3}
)