如何在 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 组模式递归
    • } - 一个 } 字符。