Search code examples
regexpositive-lookbehind

Non-greedy lookbehind - selecting text between two characters with criteria


There are plenty (e.g. 1 and 2) of answers regarding a non-greedy lookbehind and a regex that selects text between two characters. But the solutions I found so far don't rely on having criteria to the text it needs to select.

Given the example below the non-greedy lookbehind effect is nullified as soon as a criteria to the text it needs to select comes into play, e.g. when (?<=>)[^<>]+(?=<) becomes (?<=>).+rary.+ring.+(?=<)

https://regex101.com/r/A4Ks1k/3

So the question is, how do I select the text, with some 'fuzzy' criteria like .*rary.*ring.*, between to specific characters, that can occur more then once and that span multiple lines?

Edit: to answer in the comments; yes, don't match < and > in between the two characters within which a match needs to be made.


Solution

  • If you don't want to match < and > then you can use the negated character class [^<>] as you already suggested in you question.

    Make the quantifier optional with the asterix * because .+ matches 1 or more times any character.

    Use that character class at the places where you now use .+

    In your regex101 example you have the s flag to have the dot match a newline. When you use [^<>]* you can omit that flag as the negated character class also matches a newline.

    (?<=>)[^<>]*rary[^<>]*ring[^<>]*(?=<)
    

    Regex demo