问题描述
我需要用Groovy regex匹配由特定前缀和后缀包围的字符串(或字符) not 。
字符串要求:
- 不要在两个或三个{字符和0或无限的空格之前-
[\{]{2,3}\s*
- 后跟0或无限空格以及两个或三个}字符-
\s*[\{]{2,3}
一些例子:
blah string blah string blah <- two matches
string <- match
{{ string <- match
{{string} <- match
string }} <- match
{string} <- match
{{string}} <- no match
{{ string}} <- no match
{{{string }}} <- no match
{{{ string }}} <- no match
到目前为止,我只剩下(?<!\{{2})string(?!\s*\}{2,})
了,但它不能按预期工作,因为:
-
负向超前和向后负向不是“与”,因此例如
- 后面的负数必须具有固定的长度,因此我不能将0应用于无限的空白
string }}
不匹配
您有任何想法如何使用Groovy regex解决此问题吗?
解决方法
您可以将正则表达式和逻辑结合起来,如下所示:
def list = [
// match
"string","{{ string","{{string}","string }}","{string}",// two matches
"blah string blah string blah",// no matches
"{{string}}","{{ string}}","{{{string }}}","{{{ string }}}"
]
list.each {
s -> println s.replaceAll(~/(\{*)( *)(string)( *)(\}*)/,{
if(it[1].length() != it[5].length() || (it[1].length() == it[5].length() && it[1].length() <= 1 )) {
it[0] = it[1]+it[2]+"CHANGED"+it[4]+it[5]
} else it[0]
})
}
说明
正则表达式(\{*)( *)(string)( *)(\}*)
的工作原理如下:
-
(\{*)
捕获{
的所有实例 -
( *)
捕获空格(以便我们可以放回它们) -
(string)
捕获字符串(您实际上并不需要捕获它,但是它允许您对其进行测试或根据需要进行操作-例如将其大写) -
( *)
与以前的空间捕获相同 -
(\}*)
捕获}
的所有实例
代码逻辑遍历list
中的每个项目,并通过我们的正则表达式替换函数运行它。 regex replace函数测试捕获以确保满足以下两个条件之一:
-
{
的数量不等于}
的数量 -
{
的数量等于}
的数量,但是存在一个或更少的{
:
- 此匹配
{string}
或string
,但不匹配{{string}}
然后,将字符串it[0]
替换为相应的部分。您可以根据自己的喜好对其进行修改,但是根据您的原始问题,这似乎是您要查找的输出:
输出
我将string
替换为CHANGED
。
CHANGED
{{ CHANGED
{{CHANGED}
CHANGED }}
{CHANGED}
blah CHANGED blah CHANGED blah
{{string}}
{{ string}}
{{{string }}}
{{{ string }}}