views:

1001

answers:

3

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:

  1. 234654
  2. 24-3+-2
  3. -234
  4. 25485+

Invalid:

  1. ++--+
+5  A: 

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.)

Michael Myers
Beat me to it, my exact thought too.
Ben S
But is 2+++5 legal? It is with your regex.
0x6adb015
If "24-3+-2" is legal (and it seems to be), then I would guess that 2+++5 is legal also.
Michael Myers
2+++5 should be legal from the description: "a string can contain numbers, dashes and pluses, or only numbers."
Ben S
@mmyers: 24 - 3 + (-2) is a valid math expression. 2 +++ 5 is not...
0x6adb015
Well, the question doesn't mention anything about valid math expressions.
Jon Freeland
If 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.
Michael Myers
+1  A: 
^([+-]*[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+-]+
Daniel Brückner
+6  A: 

How about this:

([+-]?\d+[+-]?)+

which means "one or more sequences of 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
RichieHindle