Reputation: 2027
I am new to regex. I found a solution for my following problem, but I want to know why my first snippet is not working:
Assume I want to match with (Python) regex c
,[a]c
or [b]c
(this is MWE, in reality a,b,c represent more complex patterns).
I figured out:
Not working snip:
^(\[(a)?|(b)?\])?c$
This is matching c
, but it is not matching [a]c
or [b]c
If I remove the outer optional group so \[(a)?|(b)?\]c$
, it matches [a]z
and [b]z
but understandable not c
I can fix this by going for:
Working snip:
^(\[a\])|(\[b\])?c$
Can someone explain me why this latest is working and the first one is not?
Upvotes: 2
Views: 979
Reputation: 626845
You should have grouped the a
and b
alternatives:
^(\[(?:(a)|(b))\])?c$
^^^ ^
See the regex demo. If you do not do it, the [
is only matched before a
, and ]
is only matched after b
. And your regex matches [ac
, b]c
, ]c
, [c
strings, see your regex demo and the diagram:
See the fixed regex details below:
^
- start of the string(
- start of the first capturing group:
\[
- a literal [
(?:
- start of a non-capturing group:
(a)
- a capturing group matching a
|
- or(b)
- a capturing group matching b
)
- end of the non-capturing group\]
- a ]
)?
- end of the first capturing group, and ?
makes it match 1 or 0 timesc
- a c
$
- end of string.A fixed regex diagram:
P.S. These diagrams are generated at https://jex.im/regulex.
Upvotes: 4
Reputation: 741
I think if you want to match c, [a]c or [b]c then the you should use the expression below instead.
^((\[a\])?|(\[b\])?)?c$
Upvotes: 0
Reputation: 1410
Your first regex behavior:
Obviously, it has no valid path to represent [a]c.
Upvotes: -1