robert
robert

Reputation: 2027

RegEx: Optional not working

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

Answers (3)

Wiktor Stribiżew
Wiktor Stribiżew

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:

enter image description here

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 times
  • c - a c
  • $ - end of string.

A fixed regex diagram:

enter image description here

P.S. These diagrams are generated at https://jex.im/regulex.

Upvotes: 4

Richard Ackon
Richard Ackon

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

ashburshui
ashburshui

Reputation: 1410

Your first regex behavior:

enter image description here

Obviously, it has no valid path to represent [a]c.

Upvotes: -1

Related Questions