正则表达式不在括号中

RegEX not in brackets

我需要用不在括号中的竖线拆分文本。这是示例文本

I {need|want|{ask|prefer}} you to {help {Jason|Maria|Santa|{Lucia|Raul}'s father}|go to school} 

我找到了这个/\|(?![^{]*})/g 这里:regex, extract string NOT between two brackets

现在当我想用管道分割这部分字符串时

help {Jason|Maria|Santa|{Lucia|Raul}'s father}|go to school 

它还会选择 Jason、Maria 和 Santa 之间的管道,因为它们后面有一个左括号。如果不在任何括号中,如何更改正则表达式以仅匹配管道。

测试字符串:

help {Jason|Maria|Santa|{Lucia|Raul}'s father}|go to school

应该return

help {Jason|Maria|Santa|{Lucia|Raul}'s father}
go to school

.

Jason|Maria|Santa|{Lucia|Raul}'s father

应该return

Jason
Maria
Santa
{Lucia|Raul}'s father

您可以使用 SKIP-FAIL regex:

'~(\{(?:[^{}]++|(?1))*})(*SKIP)(*F)|\|~'

regex demo

详情

  • (\{(?:[^{}]++|(?1))*})(*SKIP)(*F) - 匹配平衡花括号之间的子字符串并跳过此匹配
    • (\{(?:[^{}]++|(?1))*}) - 捕获第 1 组匹配 {,然后 0+ 重复 {} 以外的 1+ 个字符,或者递归整个第 1 组模式((?1) 是正则表达式子例程),然后 } (平衡花括号子串)
    • (*SKIP)(*F) - 使正则表达式引擎匹配失败并跳过匹配文本从匹配结束继续匹配的PCRE动词
  • | - 或
  • \| - 匹配要拆分的文字管道。

PHP demo:

$re = '~(\{(?:[^{}]++|(?1))*})(*SKIP)(*F)|\|~';
$str = "Jason|Maria|Santa|{Lucia|Raul}'s father";
print_r( preg_split($re, $str) );

输出:

Array
(
    [0] => Jason
    [1] => Maria
    [2] => Santa
    [3] => {Lucia|Raul}'s father
)