在正则表达式中实现负向先行以排除包含特定字符串的代码块

问题描述 投票:0回答:1

这是我在here发布的原始问题的后续,但我希望能够帮助您扩展其功能。我试图从中捕获以下字符串(我们称之为输出):

ltm pool TEST_POOL { 
    Some strings
    above headers
    records { 
        baz:1 {
            ANY STRING
            HERE
            session-status enabled
        } 
        foobar:23 { 
            ALSO ANY
            STRING HERE
            session-status enabled
        }
    }
    members {
        qux:45 {
            ALSO ANY
            STRINGS HERE
            session-status enabled
        }
        bash:2 {
            AND ANY
            STRING HERE
            session-status user-disabled
        }
        topaz:789 {
            AND ANY
            STRING HERE
            session-status enabled
        }        
    }
    Some strings
    below headers
}

考虑输出的每一行都由典型的换行符分隔。为了解决这个问题,我们将

records
members
称为“标题”,将
baz
foobar
qux
bash
topaz
称为“标题”。我正在尝试在 Java 中制定一个正则表达式,它将捕获给定标题括号之间的所有标题,除了那些在自己的标题括号之间包含字符串
session-status user-disabled
的标题,如上所示。例如,假设我们想使用以下代码查找标题
members
的所有标题:

String regex = "(?:\\bmembers\\s*\\{|(?<!^)\\G[^{]+\\{[^}]+\\})\\s*?\\n\\s*([^:{}]+)(?=:\\d)";
final Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(output);
while (matcher.find()) {
    System.out.println(matcher.group(1));
}

输出应该只是...

qux
topaz

因此,它应该排除

bash
标头,因为它的括号之间有
session-status user-disabled
。我在用于实现此目的的正则表达式中实现负前瞻时遇到问题。此外,
baz
foobar
也不应该匹配,因为它们一起包含在不同“标题”的括号内。可以有任意数量的标题和任意数量的标题。修改我的正则表达式以包含负向前瞻来解决此问题的一些帮助将非常感激。

java regex regex-lookarounds
1个回答
1
投票

我在之前的表达式的基础上添加了一个替换,如果它包含字符串

session-status user-disabled
,它将尝试使用非捕获组来匹配任何“标头”。这样做时,这些“标头”将被否定,因为它们未被捕获。只有包含字符串
session-status enabled
的“headers”标题才会被匹配。

示例在这里

(?:\bmembers\s*\{|(?<!^)\G)\s*?\n\s*(?:(?:[^{]*\{[^}]*?session-status user-disabled[^}]*\})|([^:{}]+)(?=:\d)[^{]*\{[^}]*\})
© www.soinside.com 2019 - 2024. All rights reserved.