It could be done in a pseudo-conditional way, but the cure might be worse than the sickness.
The only way I would use something like this (below) is if the 'text' (abc
in this case) were something very big to where factoring it out in this way would yield time gains over including it in each alternation as it exists now. An example of some text that would be very large might be 'abc[^\d]+432xyz
', or anything that has open-ended quantifiers or that cause huge backtracking.
This works in Java ..
"^(?:1()|2()|3())abc(?:(?=\\1)\\d{2}|(?=\\2)\\d{3}|(?=\\3)\\d{4})$"
(expanded)
^ # Begin, all capture buffers are undefined and empty
(?:
1() # If '1' found, set capture buffer 1 to defined (but empty)
| 2() # If '2' found, set capture buffer 2 to defined (but empty)
| 3() # If '3' found, set capture buffer 3 to defined (but empty)
)
abc # The text factored out
(?:
# The below could also be \1\d{2}|\2\d{3}|\3\d{4} as well
(?=\1)\d{2} # Assertion: is capt buffer 1 defined?, get next two digits
| (?=\2)\d{3} # or, Assertion: is capt buffer 2 defined?, get next three digits
| (?=\3)\d{4} # or, Assertion: is capt buffer 3 defined?, get next four digits
)
$ # End
Also, as someone mentioned, you could do a general capture, then post-process the result to decide if it is valid.
Something like this: ^(1|2|3)abc(\d{2,4})$
. then do a switch on capture buffer 1, then cases on the length of capture buffer 2.