【问题标题】:How to match string not surrounded by specific prefix and suffix with regex如何使用正则表达式匹配没有被特定前缀和后缀包围的字符串
【发布时间】:2020-12-16 10:33:36
【问题描述】:

我需要用 Groovy 正则表达式匹配由特定前缀和后缀包围的字符串(或字符)

对字符串的要求:

  • 前面没有两个或三个 { 字符和 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

到目前为止,我只有(?&lt;!\{{2})string(?!\s*\}{2,}),但它没有按预期工作,因为:

  • 负前瞻和负后瞻不是“和-ed”,例如string }} 不匹配
  • 负后视必须具有固定长度,因此我不能将 0 应用于其上的无限空白

您对如何使用 Groovy 正则表达式解决此问题有任何想法吗?

【问题讨论】:

  • 您是要捕获字符串,还是简单地匹配(布尔响应)?
  • 我认为最好使用 (\{*) *(string) *(\}*) 并简单地计算捕获组 1 和 3 中的字符 + 应用您的逻辑
  • @ctwheels 我需要用它来用不同的字符串替换所有匹配的字符串(String.replaceAll)

标签: regex groovy regex-lookarounds


【解决方案1】:

您可以将正则表达式和逻辑组合起来,如下所示:

See this code working here

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 中的每个项目,并通过我们的正则表达式替换函数运行它。正则表达式替换函数测试捕获以确保满足以下两个要求之一:

  1. { 的数量不等于 } 的数量
  2. { 的数量等于 } 的数量,但存在一个或更少的 {
  • 这匹配{string}string,但不匹配{{string}}

然后我们用相应的部分替换字符串it[0]。您可以根据自己的喜好对其进行修改,但根据您的原始问题,这似乎是您正在寻找的输出:

输出

我将string 替换为CHANGED

CHANGED
{{ CHANGED
{{CHANGED}
CHANGED }}
{CHANGED}
blah CHANGED blah CHANGED blah
{{string}}
{{ string}}
{{{string }}}
{{{ string }}}

【讨论】:

    猜你喜欢
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    相关资源
    最近更新 更多