Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-greedy regex does not pick the closest choice

Tags:

regex

My regex does not pick the closest 'cont' pair to the inner text. How can I fix that?

Input:

cont cont ItextI /cont /cont

Regex:

cont.*?I(.*?)I.*?/cont

Match:

cont cont ItextI /cont

Match I need:

cont ItextI /cont
like image 940
snowindy Avatar asked Dec 09 '22 02:12

snowindy


1 Answers

cont(?:(?!/?cont).)*I(.*?)I(?:(?!/?cont).)*/cont

will only match the innermost block.

Explanation:

cont        # match "cont"
(?:         # Match...
 (?!/?cont) # (as long as we're not at the start of "cont" or "/cont")
 .          # any character.
)*          # Repeat any number of times.
I           # Match "I"
(.*?)       # Match as few characters as possible, capturing them.
I           # Match "I"
(?:         # Same as above
 (?!/?cont)
 .
)*
/cont       # Match "/cont"

This explicitly forbids cont or /cont to appear between the opening cont and the to-be-captured text (and between that text and the closing /cont).

like image 74
Tim Pietzcker Avatar answered Dec 14 '22 22:12

Tim Pietzcker