1

Assuming I have a set of numbers (from 1 to 22) divided by some trivial delimiters (comma, point, space, etc). I need to make sure that this set of numbers does not contain any repetition of the same number. Examples:

1,14,22,3 // good
1,12,12,3 // not good

Is it possible to do via regular expression?

I know it's easy to do using just php, but I really wander how to make it work with regex.

Madbreaks
  • 17,159
  • 7
  • 50
  • 64
user1520978
  • 81
  • 1
  • 3

3 Answers3

2

Yes, you could achieve this through regex via negative looahead.

^(?!.*\b(\d+)\b.*\b\1\b)\d+(?:,\d+)+$
  • (?!.*\b(\d+)\b.*\b\1\b) Negative lookahead at the start asserts that the there wouldn't be a repeated number present in the match. \b(\d+)\b.*\b\1\b matches the repeated number.

  • \d+ matches one or more digits.

  • (?:,\d+)+ One or more occurances of , , one or more digits.

  • $ Asserts that we are at the end .

DEMO

OR

Regex for the numbers separated by space, dot, comma as delimiters.

^(?!.*\b(\d+)\b.*\b\1\b)\d+(?:([.\s,])\d+)(?:\2\d+)*$

(?:([.\s,])\d+) capturing group inside this non-capturing group helps us to check for following delimiters are of the same type. ie, the above regex won't match the strings like 2,3 5.6

DEMO

Avinash Raj
  • 160,498
  • 22
  • 182
  • 229
  • 2
    Without any kind of explanation, this answer is incomplete. – Madbreaks Dec 16 '14 at 18:55
  • Thanks Avinash Raj, not sure I've get it. Currently I have an agly one like this: ^([,.:\s]+(1\d{1}|2[0-2]{1}|\d{1})[,.:\s]+(1\d{1}|2[0-2]{1}|\d{1})[,.:\s]+(1\d{1}|2[0-2]{1}|\d{1}))$ How would I apply your solution to this one? or I just start over.. – user1520978 Dec 16 '14 at 19:02
  • @madbreaks I've used the same online tool – user1520978 Dec 16 '14 at 19:04
0

You can use this regex:

^(?!.*?(\b\d+)\W+\1\b)\d+(\W+\d+)*$
  • Negative lookahead (?!.*?(\b\d+)\W+\1\b) avoids the match when 2 similar numbers appear one after another separated by 1 or more non-word characters.

RegEx Demo

Community
  • 1
  • 1
anubhava
  • 664,788
  • 59
  • 469
  • 547
0

Here is the solution that fit my current need:

^(?>(?!\2\b|\3\b)(1\d{1}|2[0-2]{1}|\d{1}+)[,.; ]+)(?>(?!\1\b|\3\b)(1\d{1}|2[0-2]{1}|\d{1}+)[,.; ]+)(?>(?!\1\b|\2\b)(1\d{1}|2[0-2]{1}|\d{1}+))$

It returns all the sequences with unique numbers divided by one or more separator and also limit the number itself from 1 to 22, allowing only 3 numbers in the sequence.

See working example

Yet, it's not perfect, but work fine! Thanks a lot to everyone who gave me a hand on this!

user1520978
  • 81
  • 1
  • 3
  • Well, that's more requirements now... Here's a [shorther one](https://regex101.com/r/bO9hN5/2) that might work for you: `^(?>([1-9]|1\d|2[0-2])\b(?!.*?\b\1\b)[ .,;]*){3}$` – Jonny 5 Dec 18 '14 at 09:34