Search code examples
regexregex-greedy

How to regex match "{ * various * strings * }" out of many instances in a non-greedy way?


I'm struggling to come up with something that works here.

Environment: Notepad++ 7.8.7 (32-bit) on Windows 10 (64-bit), some testing with regex101.com

I have a game config file that contains a whole bunch of this:

{ apple
banana
cherry 
}
{ banana
cherry
grape
}
{ cherry
grape
apple
orange
cherry
grape
}
etc., etc.

I need to match individual occurrences of { * specific * words * } where the *s DO NOT contain { or } (i.e. singular bracket blocks should be considered single matches, and no matches should contain more than one bracket block). There's no nested brackets, making things a bit simpler.

So given the example above I'd like to match something like { * apple * }, or { * apple * cherry * }, which would match the 1st and 3rd bracket block, but not the 2nd.

I've tried many dozens of variations on something like (?s){.+?apple.+?}, but they all either match nothing, have errors or timeout regex101.com (even with extended timeouts), or are too greedy, ignoring boundaries between bracket blocks.

Any insights are much appreciated.


Solution

  • You are running into issues because if you want to match {, you have to escape it with a backslash or put it in brackets: [{]. Also, . usually doesn't match newlines unless you add a newline flag.

    I think this is what you want:

    [^{]*apple[^}]*cherry[^}]*
    

    The [^}]* means match any character other than } as many times as necessary.

    Demo