Regex Negative Lookahead没有按预期工作

时间:2015-03-13 04:56:08

标签: python regex perl

我试图在两个最接近的短语之间捕捉文字,包括那些短语,但负面的前瞻似乎并不适用于我的情况。

所以,这是文本文件的一部分:

<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>

我需要捕获每对<if>...</if><wav>...</wav>标记。

我的正则表达式是:<if>.*?<\/if>(?:(?!<if>.*?<\/if>).)*?<wav>.*?<\/wav>

Regex101示例:https://regex101.com/r/eT4wJ9/1

出于某种原因,如果出现两次或更多次<if>...</if>标记,则此正则表达式会匹配从第一次出现开始的所有内容,尽管前景为负。为什么会这样?

1 个答案:

答案 0 :(得分:1)

您还需要在if块中添加否定前瞻,以便它不会与嵌套的if标记匹配。

<if>(?:(?!</?if>).)*<\/if>(?:(?!<if>.*?<\/if>).)*?<wav>(?:(?!</?wav>).)*<\/wav>

DEMO

示例:

>>> 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>