4

I'm looking for a regex to match repeating number sequences. The number/range itself could be any three digit number, for e.g. I want to match

345
346-348
234,235,236,237-239
234, 235, 236, 237-239
234,234, 236 and 237-239
234,234, 236 or 237-239

I don't want to match

3454
111-222-333
454,4567 (match only 454)

The number could be any three digit number. I tried different regexs with \d{3} in the mix, but I've not found anything that works. Appreciate any help on this.

Bob76
  • 477
  • 1
  • 5
  • 12
  • 1
    I'm confused, how is `345` a repeating number sequence? – MonkeyZeus May 04 '21 at 17:00
  • I've read this a few times but cannot work out what the criteria are. Do you mean that you want to match the literal character sequence "346-348" or that you want to match any of "346", "347", and "348"? Why is "345" desired but not "3454"? Can you define "repeating number sequence" more explicitly? – Bobulous May 04 '21 at 18:42
  • 1
    I was looking to match any three digit number (s) and three digit number ranges – Bob76 May 04 '21 at 18:44
  • So you would not want to match the literal character sequence "234, 235, 236, 237-239" but you would want to match any of "234", "235", "236", and/or "237-239"? If so, then I request that you edit your question to simply say that you want to match three-digit numbers and three-digit ranges (technically: closed intervals of numbers, using the hyphen as a bound separator). The term "repeating number sequence" doesn't fit here, in my opinion. – Bobulous May 04 '21 at 18:49
  • @Bob76: Is `111-222-333` a valid match also? – anubhava May 04 '21 at 18:53
  • No, 111-222-333 is not a valid match – Bob76 May 04 '21 at 18:55
  • ok then make sure you check that input with all the answers below – anubhava May 04 '21 at 18:59

2 Answers2

5

You may use this regex:

^\d{3}(?:-\d{3})?(?:\s*(?:,|and|or)\s*\d{3}(?:-\d{3})?)*(?=,|$)

RegEx Demo

RegEx Details:

  • ^: Start
  • \d{3}: Match 3 digits
  • (?:-\d{3})?: optionally followed by a hyphen and 3 digits
  • (?:: Start non-capture group
    • \s*: Match 0 or more whitespaces
    • (?:,|and|or): Match a comma or and or or
    • \s*: Match 0 or more whitespaces
    • \d{3}: Match 3 digits
    • (?:-\d{3})?: optionally followed by a hyphen and 3 digits
  • )*: Start non-capture group. Repeat this group 0 or more times
  • (?=,|$): Lookahead to assert that we have a comma or End of line ahead of current position
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Works great for the first set of values; however, it does not match the 454 in 454,4567 (match only 454). Any thoughts? – Bob76 May 04 '21 at 18:01
4

With your shown samples, could you please try following.

^\d{3}(?:-\d{3}$|(?:(?:,\s*\d{3}\s*){1,3}-\d{3})|(?:,\d{3},\s*\d{3}\s*(?:and|or)\s*\d{3}-\d{3})?)*(?=,|$)

Online demo for above regex

Explanation: Adding detailed explanation for above.

^\d{3}                   ##Checking from starting of value if value starts from 3 digits.
(?:                      ##Creating 1st capturing group here.
  -\d{3}$|               ##Matching - followed by 3 digits at end of value OR.
  (?:                    ##Creating 2nd capturing group here.
     (?:,\s*\d{3}\s*){1,3} ##In a non-capturing group matching ,\s* followed by 3 digits with \s* and this whole group 3 times.
     -\d{3}              ##Followed by - 3 digits.
  )|                     ##Closing 2nd capturing group OR.
  (?:                    ##Creating 3rd capturing group here.
     ,\d{3},\s*\d{3}\s*  ##Matching , 3 digits, \s* 3 digits \s*
     (?:and|or)          ##Matching and OR or strings in a non-capturing group here.
     \s*\d{3}-\d{3}      ##Matching \s* followed by 3 digits-3digits
  )?                     ##Closing 3rd capturing group keeping it optional.
)                        ##Closing 1st capturing group here.
*(?=,|$)                 ##nd matching its 0 or more matches followed by comma OR end of line.
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93