Direct Approach
[abc]{3}
would match too many results since it would also match aab
.
In order to not double match a
you would need to remove a from the group that follows leaving you with a[bc]{2}
.
a[bc]{2}
would match too many results since it would also match 'abb'.
In order to not double match b
you would need to remove a from the group that follows leaving you with ab[c]{1}
or abc
for short.
abc
would not match all combinations so you would need another group.
(abc)|([abc]{3})
which would match too many combinations again.
This path leads you down the road of having all permutations listed explicitly in groups.
Can you create combinations so that you do not need to write out all combinations?
(abc)|(acb)
could be writtean as a((bc)|(cb))
.
(bc)|(cb)
I can not shorten that any further.
Match too many and remove unwanted
Depending on the regex engine you may be able to express AND
as a look ahead so that you can remove matches. THIS and not THAT consume THIS.
(?=[abc]{3})(?=(?!a.a))[abc]{3}
would not match aca.
This problem is now simmilar to the one above where you need to remove all combinations that would violate your permutations. In this example that is any expression containing the same character mutltiple times.
'(.)\1+' this expression uses grouping references on its own matches the same character multiple times but requires knowing how many groups exist in the expression and is very brittle Adding groups kills the expression ((.)\1+)
no longer matches. Relative back references exist and require knowledge of your specific regex engine. \k<-1>
may be what you could be looking for. I will assume .net since I happen to have a regex tester bookmarked for that.
The permutations that I want to exclude are: nn.
n.n
.nn
nnn
So I create these patterns: ((?<1>.)\k<1>.)
((?<2>.).\k<2>)
(.(?<3>.)\k<3>)
((?<4>.)\k<4>\k<4>)
Putting it all together gives me this expression, note that I used relative back references as they are in .net - your milage may vary.
(?=[abc]{3})(?=(?!((?<1>.)\k<1>.)))(?=(?!((?<2>.).\k<2>)))(?=(?!(.(?<3>.)\k<3>)))(?=(?!((?<4>.)\k<4>\k<4>)))[abc]{3}
The answer is yes for a specific length.
Here is some testing data.