1

当开头和结尾的长度相同时,如何制作匹配的正则表达式?例如

>>> String = '[[A], [[B]], [C], [[D]]]'
>>> Result = re.findall(pattern, String)
>>> Result
>>> [ '[A]', '[[B]]', '[C]', '[[D]]' ]

目前我使用该模式\[.*?\],但它导致

>>> ['[[A]', '[[B]', '[C]', '[[D]']

提前致谢。

4

3 回答 3

4

您可以为有限数量的开始/结束字符定义这样的正则表达式(例如,“如果它以 1 开始和结束,或者以 2 开始和结束,等等”)。但是,您不能对无限数量的字符执行此操作。这只是正则表达式的一个事实。正则表达式是有限状态机的语言,有限状态机不能计数;至少需要下推自动机(上下文无关语法)的力量。

简而言之,正则表达式可以说:“我看到x然后我看到y ”,但它不能说“我看到x然后我看到y的次数相同”,因为它不记得看到x多少次。

但是,您可以使用图灵完备的 Python 编程语言的全部功能轻松做到这一点!图灵完备的语言绝对可以计算:

>>> string = '[[A], [[B]], [C], [[D]]]'
>>> sameBrackets = lambda s: len(re.findall('\[',s)) == len(re.findall('\]',s))
>>> filter(sameBrackets, string.split(", "))
['[[B]]', '[C]']
于 2012-05-06T06:28:16.063 回答
3

你不能。对不起。

Python 的正则表达式是“有限状态自动机”的扩展,它只允许在您扫描字符串以进行匹配时保留有限数量的内存。此示例需要任意数量的内存,具体取决于重复次数。

Python 允许的不仅仅是有限状态的唯一方法是使用“反向引用”,它允许您匹配字符串先前匹配部分的相同副本 - 但它们不允许您匹配某些内容,例如相同数量的字符。

相反,您应该尝试手写。

于 2012-05-06T06:30:30.467 回答
0

要匹配平衡括号,您需要一个递归正则表达式。stockre模块不支持这种语法,但替代的正则表达式支持:

import regex

r = r'\[(([^\[\]]+)|(?R))*\]'

print regex.match(r, '[[A], [[B]], [C], [[D]] ]') # ok
print regex.match(r, '[[A], [[B]], [C , [[D]] ]') # None

该表达式基本上是说:匹配被括号包围的东西,其中“某物”是一系列非括号([^\[\]]+)或整个东西(?R)

于 2012-05-06T11:17:36.293 回答