Paulo Paulo - 24 days ago 8
Python Question

Python regex: matching a parenthesis within parenthesis

I've been trying to match the following string:

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


But unfortunately my knowledge of regular expressions is very limited, as you can see there are two parentheses that need to be matched, along with the content inside the second one
I tried using
re.match("\(w*\)", string)
but it didn't work, any help would be greatly appreciated.

Answer

Try this:

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)

Output:

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

Explanation:

outer matches the first-starting group of parentheses using \( and \); by default search finds the longest match, giving us the outermost ( ) pair. The match m contains exactly what's between those outer parentheses; its content corresponds to the .+ bit of outer.

innerre matches exactly one of your ('a', 'b') pairs, again using \( and \) to match the content parens in your input string, and using two groups inside the ' ' to match the strings inside of those single quotes.

Then, we use findall (rather than search or match) to get all matches for innerre (rather than just one). At this point results is a list of pairs, as demonstrated by the print loop.

Update: To match the whole thing, you could try something like this:

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