Implementing a Negative Lookahead in Regex to exclude a block of code if it contains a certain string

倾然丶 夕夏残阳落幕 提交于 2019-12-11 10:27:10

问题


This is a follow up to an original question I posted here, but I would appreciate help in expanding its capabilities a bit. I have the following string I am trying to capture from (let's call it output):

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
}

Consider each line of output to be separated by a typical line break. For the sake of this question, let's refer to records and members as "titles" and baz, foobar, qux, bash, and topaz as "headers". I am trying to formulate a regex in Java that will capture all headers between the brackets of a given title EXCEPT those that contain the string session-status user-disabled between their own header brackets as can be seen above. For example, given we want to find all headers of title members with this code:

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));
}

The output should be just ...

qux
topaz

Thus, it should exclude the bash header because it has session-status user-disabled in between its brackets. I'm having trouble implementing a negative lookahead in the regex I'm using to accomplish this. In addition, baz and foobar should also not match because they are contained within the brackets of a different "title" all together. There can be any number of titles and any number of headers. Some help in modifying my regex to include a negative lookahead to solve this problem would be much appreciated.


回答1:


I built off of your previous expression and added an alternation that will attempt to match any "header" using a non-capturing group if it contains the string session-status user-disabled. In doing so, those "headers" will be negated because they aren't captured. Only titles of "headers" that contain the string session-status enabled will be matched.

Example Here

(?:\bmembers\s*\{|(?<!^)\G)\s*?\n\s*(?:(?:[^{]*\{[^}]*?session-status user-disabled[^}]*\})|([^:{}]+)(?=:\d)[^{]*\{[^}]*\})


来源:https://stackoverflow.com/questions/34338301/implementing-a-negative-lookahead-in-regex-to-exclude-a-block-of-code-if-it-cont

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!