I have a provided array of symbols, which can be different. For instance, like this - ['@']. One occurrence of each symbol is a mandatory. But in a string there can be only one of each provided sign. Now I do like this:
const regex = new RegExp(`^\\w [${validatedSymbols.join()}]\\w $`);
But it also returns an error on signs like '=' and so on. For example:
/^\w [@]\w $/.test('string@=string') // false
So, the result I expect:
- 'string@string' - ok
- 'string@@string - not ok
None of the existing answers, didn't help me :(
CodePudding user response:
Using a complex regex is most likely not the best solution. I think you would be better of creating a validation function.
In this function you can find all occurrence of the provided symbols
in string
. Then return false
if no occurrences are found, or if the list of occurrences contains duplicate entries.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
const escapeRegExp = (string) => string.replace(/[.* ?^${}()|[\]\\]/g, '\\$&');
function validate(string, symbols) {
if (symbols.length == 0) {
throw new Error("at least one symbol must be provided in the symbols array");
}
const symbolRegex = new RegExp(symbols.map(escapeRegExp).join("|"), "g");
const symbolsInString = string.match(symbolRegex); // <- null if no match
// string must at least contain 1 occurrence of any symbol
if (!symbolsInString) return false;
// symbols may only occur once
const hasDuplicateSymbols = symbolsInString.length != new Set(symbolsInString).size;
return !hasDuplicateSymbols;
}
const validatedSymbols = ["@", "="];
const strings = [
"string!*string", // invalid (doesn't have "@" nor "=")
"string@!string", // valid
"string@=string", // valid
"string@@string", // invalid (max 1 occurance per symbol)
];
console.log("validatedSymbols", "=", JSON.stringify(validatedSymbols));
for (const string of strings) {
const isValid = validate(string, validatedSymbols);
console.log(JSON.stringify(string), "//=>", isValid);
}
CodePudding user response:
use the curly brackets {1} besides the characters you want only single occurance.
CodePudding user response:
I think you are looking for the following:
const regex = new RegExp(`^\\w [${validatedSymbols.join()}]?\\w $`);
The question mark means 1 or 0 of the previous group.
You might also need to escape the symbols in validatedSymbols
as some symbols have a different meaning in regex
Edit:
For mandatory symbols it would be easier to add a group per symbol:
^\w (@\w*){1}(#\w*){1}\w $
Where the group is:
(@\w*){1}