Optional characters in a regex
Solution 1
How about:
^[0-9+-]*[0-9][0-9+-]*$
This ensures that there is at least one digit somewhere in the string. (It looks like it might have a lot of backtracking, though. But on the other hand it doesn't have a + or * wrapped inside another + or *, which I don't like either.)
Solution 2
How about this:
([+-]?\d[+-]?)+
which means "one or more digits, each of which can be preceded or followed by an optional plus or minus".
Here's a Python test script:
import re
TESTS = "234654 24-3+-2 -234 25485+ ++--+".split()
for test in TESTS:
print test, ":", re.match(r'([+-]?\d[+-]?)+', test) is not None
which prints this:
234654 : True
24-3+-2 : True
-234 : True
25485+ : True
++--+ : False
Solution 3
^([+-]*[0-9]+[+-]*)+$
Another solution using a positive look behind assertion ensuring there is at leat one number.
^[0-9+-]+$(?<=[0-9][+-]*)
Or using a positive look ahead assertion.
(?=[+-]*[0-9])^[0-9+-]+
Martin
Updated on June 05, 2022Comments
-
Martin almost 2 years
The task is pretty simple, but I've not been able to come up with a good solution yet: a string can contain numbers, dashes and pluses, or only numbers.
^[0-9+-]+$
does most of what I need, except when a user enters garbage like "+-+--+"
I've not had luck with regular lookahead, since the dashes and pluses could potentially be anywhere in the string.
Valid strings:
- 234654
- 24-3+-2
- -234
- 25485+
Invalid:
- ++--+
-
0x6adb015 almost 15 yearsBut is 2+++5 legal? It is with your regex.
-
Ben S almost 15 years2+++5 should be legal from the description: "a string can contain numbers, dashes and pluses, or only numbers."
-
Jonathan Freeland almost 15 yearsWell, the question doesn't mention anything about valid math expressions.
-
palantus almost 15 yearsIf it is math expressions he's aiming for, an expression tree would be much better than a regex. But I notice that * and / are not allowed, so I don't think it's supposed to be math.
-
ridgerunner about 13 yearsAlmost good! The only problem is when you add anchors to this expression like so:
^([+-]?\d+[+-]?)+$
this will experience Catastrophic Backtracking when presented with a non-matching string like this:01234567890123456789X
The problem is that this is essentially:(\d+)+
which is a recipe for disaster for a backtracking regex engine. To fix this, simply remove the+
from the\d+
like so:^([+-]?\d[+-]?)+$
- which works beautifully. Fix it and you'll get my +1. -
ridgerunner about 13 years
^([+-]*[0-9]+[+-]*)+$
will go pathological on non-matches (see my comment to Richies's solution). The^[0-9+-]+$(?<=[0-9][+-]*)
won't work because it uses variable length lookbehind (only .NET and JGSoft have that).(?=[+-]*[0-9])^[0-9+-]+
is ok but no need for the lookahead - just use^[-+]*\d[\d+-]*$
directly. -
ridgerunner about 13 yearsYour welcome. I've learned that it is most important to test for cases that don't match - that's where most of the problems lurk. +1