正则表达式匹配括号内的字符串

时间:2015-01-23 15:29:38

标签: python regex

我正在尝试匹配括号括起来的所有字符串。例如,对于以下字符串:

((5.85B8.5V + ?; 1.79") + (6.78A0 + ?; .97"); 4.760")

我希望匹配以下所有内容:

  • 5.85B8.5V + ?; 1.79"
  • 6.78A0 +?; 0.97"
  • (5.85B8.5V + ?; 1.79“)+(6.78A0 + ?; .97”); 4.760"

我从来没有真正掌握正则表达式,所以我遇到了麻烦。我现在拥有的是:

pattern = '\((.*?)\)'
m = re.match(pattern, string)
print m.group()
'((5.85B8.5V + ?; 1.79")'

这有点接近,但得到两种类型的第一个括号,而不是开括号和右括号。有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

正则表达式在解析嵌套结构方面不好,但是,有些方言提供了递归运算符?R?n,可以帮助您解决这个问题。 Python的股票re不支持它,但幸运的是,有regex模块可以做到:

>>> import regex
>>> s = '((5.85B8.5V + ?; 1.79") + (6.78A0 + ?; .97"); 4.760")'
>>> regex.findall(r'(?=(\((?:[^()]|(?1))*\)))', s)
['((5.85B8.5V + ?; 1.79") + (6.78A0 + ?; .97"); 4.760")', '(5.85B8.5V + ?; 1.79")', '(6.78A0 + ?; .97")']

也就是说,正则表达式不是解析通用上下文无关语言(你的字符串显然属于它)的最佳选择。考虑使用真正的解析器,你可以使用pyParsing或类似的包构建,或者只是手工编写代码 - 这在这里相当简单:

def expressions(s):
    stack = []
    for n, c in enumerate(s):
        if c == '(':
            stack.append(n+1)
        elif c == ')':
            yield s[stack.pop():n]

for x in expressions(s):
    print x

答案 1 :(得分:1)

您可以使用re.findall,但对于您的内部分组,一次使用r'\(([^()]*)\)',一次使用(.*)(以匹配整个字符串):

>>> import pprint
>>> l= re.findall(r'\(([^()]*)\)',s)+re.findall(r'\((.*)\)',s)
>>> pprint.pprint(l)
['5.85B8.5V + ?; 1.79"',
 '6.78A0 + ?; .97"',
 '(5.85B8.5V + ?; 1.79") + (6.78A0 + ?; .97"); 4.760"']

答案 2 :(得分:1)

使用lookarounds来进行重叠匹配。

>>> s = '((5.85B8.5V + ?; 1.79") + (6.78A0 + ?; .97"); 4.760")'
>>> re.findall(r'(?=\(([^()]*|.*)\))', s)
['(5.85B8.5V + ?; 1.79") + (6.78A0 + ?; .97"); 4.760"', '5.85B8.5V + ?; 1.79"', '6.78A0 + ?; .97"']

DEMO

我们只能通过外观进行重叠匹配。如果没有外表,这是不可能做到的。所以把你的模式放在一个积极的先行断言中。

第一个

\(([^()]*|.*)\) \(与文字(符号匹配。 ()称为捕获组。 [^()]*匹配任何字符,但不匹配()零次或多次或|匹配任何字符0次或多次贪婪.*直到最后\) 1}}符号。