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)
Answer from phooji on Stack OverflowTry 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)
First of all, using \( isn't enough to match a parenthesis. Python normally reacts to some escape sequences in its strings, which is why it interprets \( as simple (. You would either have to write \\( or use a raw string, e.g. r'\(' or r"\(".
Second, when you use re.match, you are anchoring the regex search to the start of the string. If you want to look for the pattern anywhere in the string, use re.search.
Like Joseph said in his answer, it's not exactly clear what you want to find. For example:
string = "TEMPLATES = ( ('index.html', 'home'), ('base.html', 'base'))"
print re.findall(r'\([^()]*\)', string)
will print
["('index.html', 'home')", "('base.html', 'base')"]
EDIT:
I stand corrected, @phooji is right: escaping is irrelevant in this specific case. But re.match vs. re.search or re.findall is still important.
regex: match everything inside brackets including other brackets
Python: How to match nested parentheses with regex? - Stack Overflow
Can regex (python) check if a supplied equation has all the matching open and closed parenthesis?
Python: regex matching anything inside parentheses (also other parentheses) - Stack Overflow
Hi there,
I'm trying to match the inside of the most "external" brackets i.e. from Sum(x3, (x0, x1, x2)) I'd like to extract Sum(x3, (x0, x1, x2)).
I tried
import re
expr = "Sum(x3, (x0, x1, x2))"
match = re.search("(\((.*?)\))", expr)
bracket_part = match.group(1)
print(bracket_part)
yet this matches only Sum(x3, (x0, x1, x2). Of course one could simply add a ) yet it would be nice to extract (x) from expression like sin(x).
Do guys have an idea how to tell regex to match up until the very last closing bracket? Thanks a lot in advance!
As others have mentioned, regular expressions are not the way to go for nested constructs. I'll give a basic example using pyparsing:
import pyparsing # make sure you have this installed
thecontent = pyparsing.Word(pyparsing.alphanums) | '+' | '-'
parens = pyparsing.nestedExpr( '(', ')', content=thecontent)
Here's a usage example:
>>> parens.parseString("((a + b) + c)")
Output:
( # all of str
[
( # ((a + b) + c)
[
( # (a + b)
['a', '+', 'b'], {}
), # (a + b) [closed]
'+',
'c'
], {}
) # ((a + b) + c) [closed]
], {}
) # all of str [closed]
(With newlining/indenting/comments done manually)
To get the output in nested list format:
res = parens.parseString("((12 + 2) + 3)")
res.asList()
Output:
[[['12', '+', '2'], '+', '3']]
There is a new regular engine module being prepared to replace the existing one in Python. It introduces a lot of new functionality, including recursive calls.
import regex
s = 'aaa(((1+0)+1)+1)bbb'
result = regex.search(r'''
(?<rec> #capturing group rec
\( #open parenthesis
(?: #non-capturing group
[^()]++ #anyting but parenthesis one or more times without backtracking
| #or
(?&rec) #recursive substitute of group rec
)*
\) #close parenthesis
)
''',s,flags=regex.VERBOSE)
print(result.captures('rec'))
Output:
['(1+0)', '((1+0)+1)', '(((1+0)+1)+1)']
Related bug in regex: http://code.google.com/p/mrab-regex-hg/issues/detail?id=78
I wrote regex to validate the syntax of an equation, but I can't get it to fail if all open parenthesis aren't closed. I currently have the parenthesis check as an IF statement before I run the regex check, but I'd like to incorporate that validation in the regex.
I checked out using capture groups and referencing them with look behinds, but can't seem to find enough information about how to use them.
Is there a way for regex to have a conditional, like a closed parenthesis is required here if an open parenthesis was used in an earlier spot?
Here's my regex that works for all the test equations I threw at it:
(I'm sure the regex is junk, and could be vastly improved. I just slapped it together today)
valid_result = re.fullmatch(r'((\(\s)*([0-9]*\s|\.[0-9]*\s|[0-9]*\.[0-9]*\s|\.[0-9]*\s)'r'((\+|\-|\*|\/|\**)\s)'r'([0-9]*\s?|\.[0-9]*\s?|[0-9]*\.[0-9]*\s?|\.[0-9]*\s?)(\s\))*?'r'((\+|\-|\*|\/|\**)\s)?)+', self.equation)
I want to reference the first bold section (match an open parenthesis) in the second bold section (closed parenthesis) to verify if I need a closing parenthesis there. Or vice versa.
Any help would be appreciated. Thanks.
edit: I couldn't bold inline code without messing up the code. So nothing is bold.
The open parenthesis is the first thing matched on the 1st line, the closed parenthesis is matched at the end of the 3rd line.
Can someone point out the error in this regex?
r"^/(.+/),$"
regex escape character is
\not/(do not confuse with python escape character which is also\, but is not needed when using raw strings)
=>r"^\(.+\),$"^and$match start/end of the input string, not what you want to output
=>r"\(.+\),"you need to match "any" characters up to 1st occurence of
), not to the last one, so you need lazy operator+?
=>r"\(.+?\),"in case gene names could not contain
)character, you can use a faster regex that avoids backtracking
=>r"\([^)]+\),"
Without any capturing groups,
>>> import re
>>> str = """
... gi|13195623|ref|NM_024197.1| Mus musculus NADH dehydrogenase (ubiquinone) 1 alp
... ha subcomplex 10 (Ndufa10), mRNAGCCGGCGCAGACGGCGAAGTCATGGCCTTGAGGTTGCTGAGACTCGTC
... CCGGCGTCGGCTCCCGCGCGCGGCCTCGCGGCCGGAGCCCAGCGCGTGGG (etc)"""
>>> m = re.findall(r'(?<=\().*?(?=\),)', str)
>>> m
['Ndufa10']
It matches only the words which are inside the parenthesis only when the closing bracket is followed by a comma.
DEMO
Explanation:
(?<=\()In regex(?<=pattern)is called a lookbehind. It actually looks after a string which matches the pattern inside lookbehind . In our case the pattern inside the lookbehind is\(means a literal(..*?(?=\),)It matches any character zero or more times.?after the*makes the match reluctant. So it does an shortest match. And the characters in which the regex engine is going to match must be followed by),
If your problem is really just this simple, you don't need regex:
s[s.find("(")+1:s.find(")")]
Use re.search(r'\((.*?)\)',s).group(1):
>>> import re
>>> s = u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'
>>> re.search(r'\((.*?)\)',s).group(1)
u"date='2/xc2/xb2',time='/case/test.png'"
I have a text of following pattern.
9) Find the angle between (12:00 to 11:59) the hour hand and the minute hand of a clock.
10) Find the last non-zero digit of the factorial of 1234.
11) Check if a given number is nearly prime or not. A nearly prime number is a positive integer that is equal to the product of two prime numbers.
I want to match the ")" after the numbers in the beginning.
How can I do that. I am using Python.