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

32 投票
5 回答
129312 浏览
提问于 2025-04-16 13:59

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

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

但是不幸的是,我对正则表达式的了解非常有限。正如你所看到的,有两个括号需要匹配,还有第二个括号里面的内容。我试着用 re.match("\(w*\)", string) 来匹配,但没有成功,任何帮助都会非常感激。

5 个回答

3

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

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

首先,单单使用 \( 是不够的,无法匹配括号。在Python中,字符串里有一些特殊的转义序列,所以它会把 \( 解释成普通的 (。你需要写成 \\(,或者使用原始字符串,比如 r'\('r"\("

其次,当你使用 re.match 的时候,它会把正则表达式的搜索固定在字符串的开头。如果你想在字符串的任何地方查找这个模式,就要用 re.search

正如Joseph在他的回答中提到的,你想找的内容并不太明确。例如:

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

将会打印

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

编辑:

我更正一下,@phooji 说得对:在这个特定情况下,转义是无关紧要的。但 re.matchre.searchre.findall 之间的区别还是很重要的。

39

试试这个:

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 正好包含了这对外层括号之间的内容;它的内容对应于 outer 中的 .+ 部分。

innerre 则是精确匹配你的 ('a', 'b') 对,依然使用 \(\) 来匹配输入字符串中的内容括号,并且在 ' ' 内部使用两个组来匹配那些单引号里的字符串。

接着,我们使用 findall(而不是 searchmatch)来获取所有的 innerre 匹配项(而不仅仅是一个)。此时,results 是一个包含所有配对的列表,这在打印循环中得到了展示。

更新: 如果想匹配整个内容,你可以试试这样的写法:

rx = re.compile("^TEMPLATES = \(.+\)")
rx.match(w)

撰写回答