Python正则表达式:匹配括号内的括号
我一直在尝试匹配以下字符串:
string = "TEMPLATES = ( ('index.html', 'home'), ('base.html', 'base'))"
但是不幸的是,我对正则表达式的了解非常有限。正如你所看到的,有两个括号需要匹配,还有第二个括号里面的内容。我试着用 re.match("\(w*\)", string)
来匹配,但没有成功,任何帮助都会非常感激。
5 个回答
如果你的字符串看起来像是有效的Python代码,那你可以这样做:
import ast
var, s = [part.strip() for part in
"TEMPLATES = ( ('index.html', 'home'), ('base.html', 'base'))".split('=')]
result= ast.literal_eval(s)
首先,单单使用 \(
是不够的,无法匹配括号。在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.match
和 re.search
或 re.findall
之间的区别还是很重要的。
试试这个:
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
(而不是 search
或 match
)来获取所有的 innerre
匹配项(而不仅仅是一个)。此时,results
是一个包含所有配对的列表,这在打印循环中得到了展示。
更新: 如果想匹配整个内容,你可以试试这样的写法:
rx = re.compile("^TEMPLATES = \(.+\)")
rx.match(w)