7

I want to write a regex that match a list of numeric values, given in a comma-separated list, ranges allowed. Empty is not allowed.

Something like: 1-10,20-56,8,7

So far I have (([0-9]+)|([0-9]+-[0-9]+),)*[0-9]+. This does most of the job, except it misses the case of one range only (eg: 1-10 would not validate).

The checking for each range can be omitted (eg: 20-10 can be allowed as a valid range).

Any help would be appreciated.

user524657
  • 71
  • 1
  • 3

4 Answers4

8

You can use the regex;

^([0-9]+(-[0-9]+)?)(,([0-9]+(-[0-9]+)?))*$

Regex in action

codaddict
  • 445,704
  • 82
  • 492
  • 529
  • my version : ^([0-9]+)(-[0-9]+)*(,([0-9]+)(-[0-9]+)*)*$. It's more or less the same :) – poh Nov 30 '10 at 04:33
2

What you're after is one (number or range) optionally followed by zero or more: comma plus (number or range):

(?:\d+(?:-\d+)?)(?:,(?:\d+(-\d+)?))*

This uses the \d shortcut for [0-9] and the (?: ... ) non-capturing parentheses construct.

This regex doesn't allow any spaces to be included in the list. To allow those, insert the "optional space" \s* between each term:

\s*(?:\d+(\s*-\s*\d+)?)\s*(?:,\s*(?:\d+(\s*-\s*\d+)?)\s*)*
Adrian Pronk
  • 13,486
  • 7
  • 36
  • 60
1

Lets say that CORE of your patter is

([0-9]+.)|([0-9]+-[0-9]+)

It matches a single numeric value or a range. So, what you need is:

(CORE,)*CORE

And what you have is:

(CORE,)*DIGIT

Do like this and you will be fine:

(([0-9]+.)|([0-9]+-[0-9]+),)*([0-9]+.)|([0-9]+-[0-9]+)
Miguel Silva
  • 633
  • 5
  • 12
0

I think what you were looking for is:

(CORE)(,\s+CORE)*

This will allow lists that are:

CORE CORE, CORE CORE, CORE CORE, CORE, CORE

and so on.

Hope this helps,
David

David
  • 1