我想正确匹配LaTeX宏,即使是嵌套的宏。参见以下内容:
s = r'''
firstline
lr{secondlinerl{ right-to-left
lr{nested left-to-right} end RTL }
other text
}
rl{ last lr{end line
} end RTL }
'''
例如,在上面的文章中,我想将lr
宏与其内容相匹配。我尝试过以下方法,但没有一个能正确工作:
re.findall(r'(?:\lr{.*})', s, re.DOTALL)
['\lr{secondline\rl{ right-to-leftn \lr{nested left-to-right} end RTL }n other textn}n\rl{ last \lr{end line n} end RTL }']
即使是非贪婪版本在这种情况下也不起作用:
re.findall(r'(?:\lr{.*?})', s, re.DOTALL)
['\lr{secondline\rl{ right-to-leftn \lr{nested left-to-right}',
'\lr{end line n}']
我需要一些正则表达式来正确匹配它,类似于嵌套的括号,这里我为LaTeX宏嵌套了花括号。
编辑:
我想得到以下匹配:
['\lr{secondline\rl{ right-to-leftn \lr{nested left-to-right} end RTL }n other textn}',
'\lr{nested left-to-right}',
'\lr{end line n}']
如果我知道嵌套的级别,这将是完美的,就像下面这样:
[('\lr{secondline\rl{ right-to-leftn \lr{nested left-to-right} end RTL }n other textn}',1)
('\lr{nested left-to-right}',2)
('\lr{end line n}',1)]
使用PyPi regex模块(在使用pip install regex
安装后(,您可以使用
import regex
s = r'''
firstline
lr{secondlinerl{ right-to-left
lr{nested left-to-right} end RTL }
other text
}
rl{ last lr{end line
} end RTL }
'''
print( [x.group() for x in regex.finditer(r'\lr({(?:[^{}]++|(?1))*})', s, overlapped=True)] )
# => ['\lr{secondline\rl{ right-to-leftn \lr{nested left-to-right} end RTL }n other textn}', '\lr{nested left-to-right}', '\lr{end line n}']
请参阅Python演示和regex演示。
还请注意与regex.finditer
一起使用的overlapped=True
选项允许匹配嵌套出现。
详细信息:
\lr
-lr
字符串({(?:[^{}]++|(?1))*})
-第1组(定义为递归时引用(:{
-一个{
字符(?:[^{}]++|(?1))*
-零次或多次重复[^{}]++
-除了{
和}
之外的一个或多个字符,在触发回溯的情况下,不可能再次重新匹配文本(即,它是所有物匹配的(|
-或(?1)
-第1组模式重复出现}
-一个}
字符