RegEx allowing digit, dash, comma

You can use this regex,

^(?:[1-9]\d\d|[1-9]?\d)(?:-(?:[1-9]\d\d|[1-9]?\d))?(?:,\s?(?:[1-9]\d\d|[1-9]?\d)(?:-(?:[1-9]\d\d|[1-9]?\d))?)*$

Explanation:

  • ^ - Start of string
  • (?:[1-9]\d\d|[1-9]?\d) - Represents a number 0 to 999 and does not allow numbers with leading zeroes like 005
  • (?:-(?:[1-9]\d\d|[1-9]?\d))? - Optionally also allows a number separated by hyphen - so together with first regex digit, it supports numbers like 22 and 22-33 etc
  • (?:,\s?(?:[1-9]\d\d|[1-9]?\d)(?:-(?:[1-9]\d\d|[1-9]?\d))?)* - This part just supports comma separated optionally followed by a whitespace and whole of it zero or more times
  • $ - End of string

I could have used \d{1,3} to represent a number from 0 to 999 but this would allow numbers like 004 which doesn't seem to be allowed seeing your sample data. But if indeed it is okay to allow numbers like 004 or 04 then you can replace [1-9]\d\d|[1-9]?\d with \d{1,3} in my regex to make it simple.

Regex Demo


You can try

   ^[0-9]{1,3}(?:\-[0-9]{1,3})?(?:,\s?[0-9]{1,3}(?:\-[0-9]{1,3})?)*$

pattern where

   ^                             String start
   0*[0-9]{1,3}                  1 to 3 digits
   (?:\-[0-9]{1,3})?             Possible minus (-) followed 1 to 3 digits (e.g. -456)
   ?:,\s?                        Comma and at most one whitespace  
   [0-9]{1,3}(?:\-[0-9]{1,3})?)* 1 to 3 digits or range repeated zero or more times
   $                             End of string        

Demo:

  string pattern = 
    @"^[0-9]{1,3}(?:\-[0-9]{1,3})?(?:,\s?[0-9]{1,3}(?:\-[0-9]{1,3})?)*$";

  string[] tests = new string[] {
    "123",
    "1234",
    "123-456",
    "123,456",
    "1-100,134,200",
    "1,18,100",
    "1, 18, 100",
    "1,  18,100",
    "1-,18,100",
    "-2,18,100",
    "1,,18,100",
    "1, ,18,100",
    ",2,18,100",
    "1,18,100,",
  };

  string[] results = tests
    .Select(test => $"{test,-20} --> {(Regex.IsMatch(test, pattern) ? "PASS" : "FAIL")}")
    .ToArray();

  string report = string.Join(Environment.NewLine, results);

  Console.Write(report);

Outcome:

123                  --> PASS
1234                 --> FAIL 
123-456              --> PASS
123,456              --> PASS
1-100,134,200        --> PASS
1,18,100             --> PASS
1, 18, 100           --> PASS
1,  18,100           --> FAIL
1-,18,100            --> FAIL
-2,18,100            --> FAIL
1,,18,100            --> FAIL
1, ,18,100           --> FAIL
,2,18,100            --> FAIL
1,18,100,            --> FAIL

Edit:

  • If you want to allow arbitrary many leading zeros (e.g. 000123 which is in fact 123), change each [0-9]{1,3} fragment into 0*[0-9]{1,3}
  • If you want ban leading zeroes (012 must fail, when 12 or 0 must) pass, change each [0-9]{1,3} fragment into (?:0|[1-9][0-9]{0,2})

Try following pattern: ^(?:\d{1,3}-\d{1,3}|\d{1,3})(?:, ?(?:\d{1,3}-\d{1,3}|\d{1,3}))*$

Explanation:

^ - match beginning of a string

(?:...) - non-capturing group

\d{1,3} - match between 1 and 3 digits

- - match dash literally

| - alternation, match what's on the right (\d{1,3}) or what on the left (\d{1,3}-\d{1,3})

, ? - match , followed by zero or one space

* - match (?:, ?(?:\d{1,3}-\d{1,3}|\d{1,3})) zero or more times

$ - match end of a string

Demo

Tags:

C#

Regex