Python正则表达式:匹配括号内的括号

时间:2011-03-18 20:23:58

标签: python regex

我一直在尝试匹配以下字符串:

string = "TEMPLATES = ( ('index.html', 'home'), ('base.html', 'base'))"

但不幸的是,我对正则表达式的了解非常有限,因为你可以看到有两个括号需要匹配,第二个内容也是如此。 我尝试使用re.match("\(w*\)", string)但它没有用,任何帮助都会非常感激。

6 个答案:

答案 0 :(得分:26)

试试这个:

import re
w = "TEMPLATES = ( ('index.html', 'home'), ('base.html', 'base'))"

# find outer parens
outer = re.compile("\((.+)\)")
m = outer.search(w)
inner_str = m.group(1)

# find inner pairs
innerre = re.compile("\('([^']+)', '([^']+)'\)")

results = innerre.findall(inner_str)
for x,y in results:
    print("%s <-> %s" % (x,y))

<强>输出:

index.html <-> home
base.html <-> base

<强>解释

outer使用\(\)匹配首先出现的括号组;默认情况下search找到最长的匹配项,为我们提供最外面的( )对。匹配m包含这些外括号之间的确切内容;其内容对应.+的{​​{1}}位。

outer只与您的innerre对中的一个匹配,再次使用('a', 'b')\(匹配输入字符串中的内容parens,并在\)内使用两个组{1}}匹配这些单引号内的字符串。

然后,我们使用' '(而不是findallsearch)来获取match的所有匹配(而不只是一个)。此时innerre是对的列表,如打印循环所示。

更新:为了匹配整个事情,您可以尝试这样的事情:

results

答案 1 :(得分:7)

首先,使用\(不足以匹配括号。 Python通常会对其字符串中的某些转义序列做出反应,这就是为什么它将\(解释为简单(的原因。您可能需要编写\\(或使用原始字符串,例如r'\('r"\("

其次,当您使用re.match时,您正在将正则表达式搜索锚定到字符串的开头。如果要在字符串中的任何位置查找模式,请使用re.search

像约瑟夫在他的回答中所说,你想要找到的并不完全清楚。例如:

string = "TEMPLATES = ( ('index.html', 'home'), ('base.html', 'base'))"
print re.findall(r'\([^()]*\)', string)

will print

["('index.html', 'home')", "('base.html', 'base')"]

修改

我更正了,@phooji is right:逃避与此特定情况无关。但re.matchre.searchre.findall仍然很重要。

答案 2 :(得分:2)

如果你的字符串看起来像有效的Python代码,你可以这样做:

import ast
var, s = [part.strip() for part in 
     "TEMPLATES = ( ('index.html', 'home'), ('base.html', 'base'))".split('=')]
result= ast.literal_eval(s)

答案 3 :(得分:1)

你的样本正在寻找开放的paren,然后是零个或多个字母w,接着是close paren。您可能希望使用\ w而不是w,但这无论如何都不适用于您的情况,因为您在打开的paren旁边有非单词字符。

我认为您应该考虑将字符串拆分为逗号。你的最终目标是什么?

答案 4 :(得分:0)

如果要验证括号是否在两个深度之间达到平衡,可以使用以下正则表达式:

import re;

string = """( ('index.html', 'home'), ('base.html', 'base'))
('index.html', 'home')
('base.html', 'base')
"""

pattern = re.compile(r"(?P<expression>\(([^()]*(?P<parenthesis>\()(?(parenthesis)[^()]*\)))*?[^()]*\))")

match = pattern.findall(string)

print(match[0][0])
print(match[1][0])
print(match[2][0])

此正则表达式使用条件语句(?(parenthesis)[^()]*\))

演示:https://repl.it/@Konard/ParenthesesExample

答案 5 :(得分:-2)

更好地使用适当的解析模块,例如pyparsing。