tags:

views:

181

answers:

6

I have this regex code in python :

if re.search(r"\{\\fad|fade\(\d{1,4},\d{1,4}\)\}", text):
  print(re.search(r"\{\\fad|fade\((\d{1,4}),(\d{1,4})\)\}", text).groups())

text is {\fad(200,200)}Épisode 101 : {\i1}The Ghost{\i0}\Nv. 1.03 and read from a file (don't know if that helps).

This returns the following:

(None, None)

When I change the regex in the print to r"\{\\fad\((\d{1,4}),(\d{1,4})\)\}", it returns the correct values:

(200, 200)

Can anyone see why the conditional fad|fade matches the regex in the re.search but doesn't return the correct values of the groups in the print?

Thanks.

+1  A: 

I think your conditional is looking for "\fad" or "fade", I think you need to move a \ outside the grouping if you want to look for "\fad" or "\fade".

Steve Haigh
And if I want to look for "fad" or "fade"? Is there a way without grouping it like (fad|fade)? I mean, I don't want it to be found when calling .groups(). I just want the others values.
Loïc Wolff
Yes, but I think others have already given the correct examples so I'll quit while I'm up... regex's are a minefield:-)
Steve Haigh
+2  A: 

Try this:

r"\{\\fade?\(\d{1,4},\d{1,4}\)\}"
chaos
Certainly a more elegant expression, but doesn't really answer the question.
Whatsit
It fixes the heart of the problem. I think \d{1,4} should still be grouped for capture.
David Berger
It's matching "{\fad", so the search works but doesn't capture the numbers
Greg
+4  A: 

The bracket is part of the or branch starting with fade, so it's looking for either "{fad" or "fade(...". You need to group the fad|fade part together. Try:

r"\{\\(?:fad|fade)\(\d{1,4},\d{1,4}\)\}"

[Edit] The reason you do get into the if block is because the regex is matching, but only because it detects it starts with "{\fad". However, that part of the match contains no groups. You need to match with the part that defines the groups if you want to capture them.

Brian
That was my first guess too, but then why does the first regex match?
Michael Myers
The first doesn't match because | has no idea how far back or forward to look, so it looks back to the beginning, and forward to (.
David Berger
@David Berger: I actually commented on the question to say almost exactly that (and suggest a non-capturing group), but then I realized that I had no idea why that would still let the first regex match, so I deleted it. Thanks for clearing that up.
Michael Myers
+4  A: 

Put extra parens around the choice: re.search(r"{(?:\\fad|fade)\((\d{1,4}),(\d{1,4})\)}", text).groups()

Also, escaping {} braces isn't necessary, it just needlessly clutters your regexp.

Eugene Morozov
It works but I don't understand the "(?:" could you clarify, please?
Loïc Wolff
@dex: It's a non-capturing group, so it won't show up when you print the groups.
Michael Myers
@mmyers Sweet. Thank you.
Loïc Wolff
A: 

I don't know the python dialect of regular expressions, but wouldn't you need to 'group' the "fad|fade" somehow to make sure it isn't trying to find "fad OR fade(etc..."?

veefu
+1  A: 

Try this instead:

r"\{\\fade?\((\d{1,4}),(\d{1,4})\)\}"

The e? is an optional e. The way you have it now matches {\fad or fade(0000,0000)}

Greg