正则表达式 Lookahead/Lookbehind 如果出现不止一次

Regex Lookahead/Lookbehind if more than one occurance

我有这样的字符串公式:

?{a,b,c,d}

可以这样嵌入:

?{a,b,c,?{x,y,z}}

或者这是相同的:

?{a,b,c,
    ?{x,y,z}
}

所以我必须找到那些逗号,即第二个和更大的 "level" 括号中的内容。 在下面的示例中,我标记了 "levels",我必须在其中找到所有逗号:

?{a,b,c,
    ?{x,y,          <--Those
        ?{1,2,3}    <--Those
    }
}

我试过先行和后行,但我现在完全糊涂了:/

这是我最近的工作尝试,但一点也不好: OnlineRegex

更新: 为了避免误解,我不想计算逗号。 我想要一组逗号来替换它们。

条件是找到前面多于一个 "open tags" 的逗号,像这样: ?{

.. 没有这样的结束标签:}

示例: 在这种情况下,我没有替换任何逗号:

?{1,2,3} ?{a,b,c}

但在这种情况下,我必须替换 a b c 之间的逗号

?{1,2,3,?{a,b,c}}

你的问题不太清楚@norbre,但我想你想提取(即"count")逗号的数量。 你不能用正则表达式来做到这一点。正则表达式无法计算出现次数。但是,您可以使用它来提取 "internal part",然后使用电子表格公式计算逗号的数量:

^(?:\?{[a-zA-Z0-9,]+?,\n??\s*?\?{)([a-zA-Z0-9,?{}\n\s]+?(?:\n*?\s*?|})+)(?:[a-zA-Z0-9,\n\s]*})$

尝试:https://regex101.com/r/Rr0eFo/5


示例

1。 输入:

?{a,b,c,?{e,f},1,2,3}

输出:

e,f}

2。 输入:

?{a,b,c,  
    ?{x,y,z,e,  
        ?{1,2,3,?{f,g,3},4,5,6}  
}  
,d,e,f}

输出:

x,y,z,e,
        ?{1,2,3,?{f,g,3},4,5,6}
}

3。 输入:

?{a,b,c,?{e},1,2,3}

输出:

e}

(注意这里没有逗号!)


但是请注意。 正如我所说,正则表达式不能计算出现的次数。 因此,以下示例(不知道它对您的情况是否有效)将 return 错误匹配:

?{a,b,c,?{e,f}
    ,1,2,3,?{a,b}
}

输出:

e,f}
    ,1,2,3,?{a,b}

好的,替换逗号是另一回事,所以我将添加另一个答案。 您的正则表达式引擎需要支持递归。

我仍然没有看到用一个正则表达式来做到这一点的方法 - 一个匹配要么包含第一个逗号,要么包含大括号之间的所有内容!

我的建议是使用一个正则表达式来获取 "what is inside the inner braces"、运行 并使用正则表达式中的子匹配再次替换 (, => "") 和 assemble 整行。

这里是:(\?{[^?{}]*)((?>[^?{}]|(?R))+?)([^?{}]*?\})

尝试:https://regex101.com/r/IzTeY0/3

示例 1:
输入:

?{a,b,c,
    ?{x,y,z,e,
        ?{1,2,3,?{f,g,3},4,5,6}
}

,d,e,f}

子匹配项:
1. ?{a,b,c,
2. ?{x,y,z,e, ?{1,2,3,?{f,g,3},4,5,6} }
3. ,d,e,f}

用您想要的任何内容替换子匹配 2 中的所有逗号,然后使用子匹配 1 和 3 重新组合整个字符串。


同样,这会破坏正则表达式:

?{a,b,c,?{e,f}
    ,1,2,3,?{a,b}
}

子匹配 2 如下所示:

 ?{e,f}
    ,1,2,3,?{a,b}

对于您提供的示例,以下正则表达式有效(提供您提到的所需输出):

(?<!^\?{[^{}]*),(?=[\s\S]*(?:\s*}){2,})

对于字符串 ?{a,b,c,d},请参阅 Demo1 不匹配


对于字符串,?{a,b,c,?{x,y,z}},见Demo2匹配成功


对于字符串,

?{a,b,c,
    ?{x,y,z}
}

查看Demo3匹配成功


对于字符串,

?{a,b,c,
    ?{x,y,          
        ?{1,2,3}   
    }
}

查看Demo4匹配成功


对于字符串 ?{1,2,3} ?{a,b,c} ?{1,2,3} ?{a,b,c},请参阅 Demo5 不匹配


解释:

  • (?<!^\?{[^{}]*), - 否定后视以丢弃第一级逗号。这里应用的逻辑是它不应该匹配逗号,逗号前面是字符串的开头,后跟 ?{ 后跟除 {}[=67= 之外的任何字符的 0+ 次出现]
  • (?=[\s\S]*(?:\s*}){2,}) - 上面匹配的逗号后面必须跟着 atleast 出现 2 次 }(连续或它们之间只有空格)