Reputation: 63
I'm looking for a regex that will match ad-hoc groups of characters of certain length only if all its characters are unique.
For the given string example:
123132213231312321112122121111222333211221331
123, 132, 213, 231, 312, 321
are matched and
112, 122, 121, 111, 313, 322, 221, 323, 131
, etc are not matched.
I tried (?:([0-9])(?!.{3}\1)){3}
but it's completely wrong
Upvotes: 5
Views: 1570
Reputation:
This regex is from 1-10 digits, take your pick.
( \d )
(?! \1 )
( \d )
(?! \1 | \2 )
( \d )
(?! \1 | \2 | \3 )
( \d )
(?! \1 | \2 | \3 | \4 )
( \d )
(?! \1 | \2 | \3 | \4 | \5 )
( \d )
(?! \1 | \2 | \3 | \4 | \5 | \6 )
( \d )
(?! \1 | \2 | \3 | \4 | \5 | \6 | \7 )
( \d )
(?! \1 | \2 | \3 | \4 | \5 | \6 | \7 | \8 )
( \d )
(?! \1 | \2 | \3 | \4 | \5 | \6 | \7 | \8 | \9 )
\d
Upvotes: 1
Reputation: 8281
It seems that you are using python. regex is not a silver bullet and definitely not the straightforward solution to your problem (especially because the expression change with the length that you want to analyze) Writing a little code would be better and offer better performance.
Here is an example of code in Scala that solve the problem
"123132213231312321112122121111222333211221331".sliding(3).map(_.distinct).filter(_.size == 3).mkString("-")
output:
123-231-132-213-132-231-312-123-321-321-213
Upvotes: 2
Reputation: 4500
Iterate over the input string, finding a match of this expression each iteration, chopping off up to and including the first character of the previous match, until there is no match:
((\d)((?!\2)\d)((?!\2)(?!\3)\d))
You could do a findAll, but then you won't detect overlapping matches, such as "12321" would have. You'd only find the first: "123"
Of course, this only works for digits. If you want to match word characters also, you could do:
((\w)((?!\2)\w)((?!\2)(?!\3)\w))
If you want a longer length, just follow the pattern when building a regex:
((\w)((?!\2)\w)((?!\2)(?!\3)\w)((?!\2)(?!\3)(?!\4)\w))
So, I'll just hopefully Python-correct code... :
max=<your arbitrary length>
regex = "((\\w)"
for i in range(1, max-1):
regex += "("
for j in range(2, i+1):
regex +="(?!\\"+j+")"
regex += "\\w)"
regex = ")"
Phew
Upvotes: 4