Lucas Trzesniewski的评论实际上可以在Python中使用PyPi正则表达式模块(我只是用编号替换了命名组以使其更短):
>>> import regex
>>> r = regex.compile(r'({(?:[^{}]++|\g<1>)*})(*SKIP)(*FAIL)|\s*,\s*')
>>> s = """{J. Doe, R. Starr}, {Lorem
{i}psum dolor }, Dol. sit., am. et."""
>>> print(r.split(s))
['{J. Doe, R. Starr}', None, '{Lorem\n{i}psum dolor }', None, 'Dol. sit.', None, 'am. et.']
该模式 - ({(?:[^{}]++|\g<1>)*})(*SKIP)(*FAIL)
- 匹配类似于{...{...{}...}...}
的结构(其中{
匹配{
,(?:[^{}]++|\g<1>)*
匹配2种选择中的0个或多个:1)任何一个字符,除了{
和}
之外的任何一个字符([^{}]++
),2)与整个子模式({(?:[^{}]++|\g<1>)*})
相匹配的文本)。(*SKIP)(*FAIL)
动词使引擎忽略匹配值的整个部分,从而将索引移动到匹配的末尾并保持无返回内容(我们“跳过”了我们匹配的内容)。
\s*,\s*
匹配由0个或多个空格包围的逗号。
出现None
是因为第一分支中有一个捕获组,在第二分支匹配时为空。我们需要在第一个选择分支中使用一个捕获组进行递归。要删除空元素,请使用推导式:
>>> print([x for x in r.split(s) if x])
['{J. Doe, R. Starr}', '{Lorem\n{i}psum dolor }', 'Dol. sit.', 'am. et.']
(?'braces'\{(?:[^{}]++|\g<braces>)*\})(*SKIP)(*FAIL)|,
。 - Lucas Trzesniewskire
引擎直接基于Perl。而且我不确定能够在没有警告的情况下花费指数时间来处理正则表达式是否算作“超越它”。 - abarnert