In a regular expression, match one thing or another, or both
Yes, you can match all of these with such an expression:
/^[0-9]*\.?[0-9]+$/
Note, it also doesn't match the empty string (your last condition).
The fully general method, given regexes /^A$/
and /^B$/
is:
/^(A|B|AB)$/
i.e.
/^([0-9]+|\.[0-9]+|[0-9]+\.[0-9]+)$/
Note the others have used the structure of your example to make a simplification. Specifically, they (implicitly) factorised it, to pull out the common [0-9]*
and [0-9]+
factors on the left and right.
The working for this is:
- all the elements of the alternation end in
[0-9]+
, so pull that out:/^(|\.|[0-9]+\.)[0-9]+$/
- Now we have the possibility of the empty string in the alternation, so rewrite it using
?
(i.e. use the equivalence(|a|b) = (a|b)?
):/^(\.|[0-9]+\.)?[0-9]+$/
- Again, an alternation with a common suffix (
\.
this time):/^((|[0-9]+)\.)?[0-9]+$/
- the pattern
(|a+)
is the same asa*
, so, finally:/^([0-9]*\.)?[0-9]+$/
Nice answer by huon (and a bit of brain-twister to follow it along to the end). For anyone looking for a quick and simple answer to the title of this question, 'In a regular expression, match one thing or another, or both', it's worth mentioning that even (A|B|AB)
can be simplified to:
A|A?B
Handy if B is a bit more complex.
Now, as c0d3rman's observed, this, in itself, will never match AB. It will only match A and B. (A|B|AB
has the same issue.) What I left out was the all-important context of the original question, where the start and end of the string are also being matched. Here it is, written out fully:
^(A|A?B)$
Better still, just switch the order as c0d3rman recommended, and you can use it anywhere:
A?B|A