Q:

Regex Negative Lookahead doesn't work as expected

I'm trying to capture the text between two closest phrases including those phrases, but negative lookahead doesn't seem to work in my situation.
So, this is a part of the text file:
<in><il>plural</il> <if>aba*cus*es</if> <il>also</il> <if>aba*ci</if> <sound><wav>abaci001.wav</wav><wav>abaci002.wav</wav></sound> <pr>-ˌsaɪ</pr> <altpr>ˈæbəˌsaɪ</altpr></in>
<in><il>plural</il> <if>fau*nas</if> <il>also</il> <if>fau*nae</if> <sound><wav>fauna002.wav</wav></sound> <pr>ˈfɑ:ˌni:</pr></in>
<il>or</il> <if>fur*ther</if> <sound><wav>far00003.wav</wav></sound> <in><if>far*thest</if> <sound><wav>farthe03.wav</wav></sound>

I need to capture every pair of <if>...</if> and <wav>...</wav> tags.
My regex is: <if>.*?<\/if>(?:(?!<if>.*?<\/if>).)*?<wav>.*?<\/wav>
Regex101 Example: https://regex101.com/r/eT4wJ9/1
For some reason, if there're two or more occurrences of <if>...</if> tag, this regex matches everything starting from the first occurrence despite the negative lookahead. Why does it happen?

A:

You need to add a negative lookahead inside the if block also, so that it won't match the nested if tags.
<if>(?:(?!</?if>).)*<\/if>(?:(?!<if>.*?<\/if>).)*?<wav>(?:(?!</?wav>).)*<\/wav>

DEMO
Example:
>>> s = '''<in><il>plural</il> <if>aba*cus*es</if> <il>also</il> <if>aba*ci</if> <sound><wav>abaci001.wav</wav><wav>abaci002.wav</wav></sound> <pr>-ˌsaɪ</pr> <altpr>ˈæbəˌsaɪ</altpr></in>
<in><il>plural</il> <if>fau*nas</if> <il>also</il> <if>fau*nae</if> <sound><wav>fauna002.wav</wav></sound> <pr>ˈfɑ:ˌni:</pr></in>
<il>or</il> <if>fur*ther</if> <sound><wav>far00003.wav</wav></sound> <in><if>far*thest</if> <sound><wav>farthe03.wav</wav></sound>'''
>>> for i in re.findall(r'<if>(?:(?!</?if>).)*<\/if>(?:(?!<if>.*?<\/if>).)*?<wav>(?:(?!</?wav>).)*<\/wav>', s):
        print(i)

<if>aba*ci</if> <sound><wav>abaci001.wav</wav>
<if>fau*nae</if> <sound><wav>fauna002.wav</wav>
<if>fur*ther</if> <sound><wav>far00003.wav</wav>
<if>far*thest</if> <sound><wav>farthe03.wav</wav>

