0

I'm having trouble getting a regex to work using a named group and a conditional expression. I've simplified the problem to the smallest possible example.

The regex r"(?P<x>\d)(?(x)a|b)" would seem to mean "match a digit, and if you matched a digit (named group x) also match an a, but if not, match b". This should be equivalent to r"(\da|b)".

However, while it matches for the yes clause, it doesn't match the no clause:

>>> re.match(r"(?P<x>\d)(?(x)a|b)", "5a")
<re.Match object; span=(0, 2), match='5a'>
>>> re.match(r"(?P<x>\d)(?(x)a|b)", "b")
>>>

It's also not working with a numbered group:

>>> re.match(r"(\d)(?(1)a|b)", "5a")
<re.Match object; span=(0, 2), match='5a'>
>>> re.match(r"(\d)(?(1)a|b)", "b")
>>>

What am I missing?

1 Answer 1

1

The problem is the group at the start of the pattern is required to match. You can fix it by making it optional (adding a ? after it):

>>> re.match(r"(?P<x>\d)?(?(x)a|b)", "5a")
<_sre.SRE_Match object; span=(0, 2), match='5a'>
>>> 

>>> re.match(r"(?P<x>\d)?(?(x)a|b)", "b")
<_sre.SRE_Match object; span=(0, 1), match='b'>
>>> 
Sign up to request clarification or add additional context in comments.

1 Comment

Argh, right. The conditional is never evaluated because b has already failed to match, without the ?. I think I botched my example trying to simplify it. I probably should have asked about the full pattern, but I found another way to do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.