如何在 Python 中将嵌套的 LaTeX 宏与 re 匹配?
How to match nested LaTeX macros with re in Python?
我想正确匹配 LaTeX 宏,甚至是嵌套宏。请参阅以下内容:
s = r'''
firstline
\lr{secondline\rl{ right-to-left
\lr{nested left-to-right} end RTL }
other text
}
\rl{ last \lr{end line
} end RTL }
'''
例如,在上面,我想匹配 \lr
宏及其内容。我尝试了以下方法,但其中 none 工作正常:
re.findall(r'(?:\lr\{.*\})', s, re.DOTALL)
['\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right} end RTL }\n other text\n}\n\rl{ last \lr{end line \n} end RTL }']
即使是非贪婪版本在这种情况下也不起作用:
re.findall(r'(?:\lr\{.*?\})', s, re.DOTALL)
['\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right}',
'\lr{end line \n}']
我需要一些正则表达式来正确匹配它,类似于嵌套括号,这里我为 LaTeX 宏嵌套了大括号。
编辑:
我想获得以下比赛:
['\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right} end RTL }\n other text\n}',
'\lr{nested left-to-right}',
'\lr{end line \n}']
如果我知道嵌套级别就完美了,如下所示:
[('\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right} end RTL }\n other text\n}',1)
('\lr{nested left-to-right}',2)
('\lr{end line \n}',1)]
使用 PyPi 正则表达式模块(使用 pip install regex
安装后)你可以使用
import regex
s = r'''
firstline
\lr{secondline\rl{ 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-left\n \lr{nested left-to-right} end RTL }\n other text\n}', '\lr{nested left-to-right}', '\lr{end line \n}']
参见Python demo and the regex demo。
另请注意与 regex.finditer
一起使用的 overlapped=True
选项,它允许匹配嵌套事件。
详情:
\lr
- \lr
字符串
(\{(?:[^{}]++|(?1))*})
- 第 1 组(定义为在递归时引用):
\{
- 一个 {
字符
(?:[^{}]++|(?1))*
- 的零次或多次重复
[^{}]++
- 除了 {
和 }
之外的一个或多个字符,无法再次 re-match 文本以防回溯被触发(即匹配占有欲)
|
- 或
(?1)
- 第 1 组模式递归
}
- 一个 }
字符。
我想正确匹配 LaTeX 宏,甚至是嵌套宏。请参阅以下内容:
s = r'''
firstline
\lr{secondline\rl{ right-to-left
\lr{nested left-to-right} end RTL }
other text
}
\rl{ last \lr{end line
} end RTL }
'''
例如,在上面,我想匹配 \lr
宏及其内容。我尝试了以下方法,但其中 none 工作正常:
re.findall(r'(?:\lr\{.*\})', s, re.DOTALL)
['\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right} end RTL }\n other text\n}\n\rl{ last \lr{end line \n} end RTL }']
即使是非贪婪版本在这种情况下也不起作用:
re.findall(r'(?:\lr\{.*?\})', s, re.DOTALL)
['\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right}',
'\lr{end line \n}']
我需要一些正则表达式来正确匹配它,类似于嵌套括号,这里我为 LaTeX 宏嵌套了大括号。
编辑:
我想获得以下比赛:
['\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right} end RTL }\n other text\n}',
'\lr{nested left-to-right}',
'\lr{end line \n}']
如果我知道嵌套级别就完美了,如下所示:
[('\lr{secondline\rl{ right-to-left\n \lr{nested left-to-right} end RTL }\n other text\n}',1)
('\lr{nested left-to-right}',2)
('\lr{end line \n}',1)]
使用 PyPi 正则表达式模块(使用 pip install regex
安装后)你可以使用
import regex
s = r'''
firstline
\lr{secondline\rl{ 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-left\n \lr{nested left-to-right} end RTL }\n other text\n}', '\lr{nested left-to-right}', '\lr{end line \n}']
参见Python demo and the regex demo。
另请注意与 regex.finditer
一起使用的 overlapped=True
选项,它允许匹配嵌套事件。
详情:
\lr
-\lr
字符串(\{(?:[^{}]++|(?1))*})
- 第 1 组(定义为在递归时引用):\{
- 一个{
字符(?:[^{}]++|(?1))*
- 的零次或多次重复
[^{}]++
- 除了{
和}
之外的一个或多个字符,无法再次 re-match 文本以防回溯被触发(即匹配占有欲)|
- 或(?1)
- 第 1 组模式递归}
- 一个}
字符。