Reputation: 9559
I am trying to match a specific set of characters but 1 and only 1 of each.
For example if the set is [abcd]
, I want to match string containing these exact characters in any order.
abcd - true
bcad - true
abc - false (need all characters)
abbd - false
abcdd - false
From what I understand so far there is no easy way to achieve this with RegEx but no answer was conclusive enough.
Upvotes: 7
Views: 3213
Reputation: 9422
See bobble bubble's excellent answer for a real regex solution (which is sometimes necessary). This answer uses sorting and string equality instead of a single regex:
var set = 'bcad'; // in any order
var tests = [
'abcd', // true
'bcad', // true
'abc', // false (need all characters)
'abbd', // false
'abcdd', // false
];
var setSorted = set.split('').sort().join();
for (var i = 0; i < tests.length; i++) {
var pass = setSorted == tests[i].split('').sort().join();
console.log(`${tests[i]}: ${pass}`);
}
Upvotes: 1
Reputation: 5357
Just a humble contribution using grep:
grep -Px '[abcd]{4}' | grep -vP '(.).*\1'
Upvotes: 1
Reputation: 18555
I would think of capturing and using a lookahead to check if the same character is not ahead.
\b(?:([abcd])(?!\w*?\1)){4}\b
(?:
opens a non capture group for repetition\b
matches a word boundary([abcd])
captures one of [abcd]
(?!\w*?\1)
checks if the captured character is not ahead with any amount of \w
in between{4}\b
4 times until another word boundarySee demo at regex101 (works only, if a lookahead is available in your regex flavor)
Upvotes: 9
Reputation: 96016
The problem you're trying to solve is checking whether a string is a permutation of "abcd".
You don't want to use regex for every problem you have. It's useful and powerful when you have a pattern. Checking if a string is a permutations of "abcd" is not really a "pattern".
The best approach would be using the language's power and construct a solution from the functions available for you.
Upvotes: 2
Reputation: 786291
You can use a lookahead for each character to assert that char is present only once in your regex.
So e.g. for your input chars abcd
generate this regex:
^(?=[^a]*a[^a]*$)(?=[^b]*b[^b]*$)(?=[^c]*c[^c]*$)(?=[^d]*d[^d]*$)
^(?=[^a]*a[^a]*$)
will assert that a
is present only once in input. and so on for other chars b,c,d
.
Upvotes: 2