#Regex, match strings that at most contain one or more elements
11 messages · Page 1 of 1 (latest)
Use or operator ^(foo|bar|foo\/bar)$
I just realized that the example might not generalize well to my actual problem.
so it works, but it should also work for any combination of keywords, e.g. when I want to instead match "foo", "bar", "foo/bar", "foo/baz", "bar/baz" and "foo/bar/baz", the regex would need to be ^(foo|bar|baz|foo\/bar|foo\/baz|bar\/baz|foo\/bar\/baz)$
and my actual problem is how I generate that search string for any array of keywords in Javascript 😅
If you want it to be dynamic, regex is not the best option for that
You better do it through Javascript
Okay but in the end I need a regex string, since I'm going to query MongoDB with it.
So I somehow have to generate the string above for any array of words
probably a permutation problem of sorts
okay I might have found something (shamelessly borrowed from https://code-boxx.com/javascript-permutations-combinations/)
function allCombinations (items) {
let results = [];
for (let slots = items.length; slots > 0; slots--) {
for (let loop = 0; loop < items.length - slots + 1; loop++) {
let key = results.length;
results[key] = [];
for (let i = loop; i < loop + slots; i++) {
results[key].push(items[i]);
}
}
}
return results;
}
let searchStr = '^(';
let combo = allCombinations(['foo', 'bar', 'baz']);
combo.forEach(comb => {
searchStr += comb.join('\/') + '|';
});
searchStr += ')$';
let regex = RegExp(searchStr);
This beginner's tutorial will walk you through Javascript permutations and combinations - Example source code download included.
I don't know if this works in all scenarios. For example, with inputs of ['foo', 'bar', 'baz'] the output is ^(foo/bar/baz|foo/bar|bar/baz|foo|bar|baz|)$ which looks like it's missing a few
like you have foo/bar but do you also need bar/foo?
I think this might work:
function addWords(wordstack, wordlist){
var result = wordstack;
var stackEmpty = wordstack == ""
var delimiter = stackEmpty ? "" : "\\/";
for(var i = 0; i < wordlist.length; i++){
let newList = [...wordlist]
newList.splice(i, 1)
result += "|" + addWords(wordstack + delimiter + wordlist[i], newList)
}
return result;
}
function makeRegex(wordlist){
if(wordlist.length == 0)
return null;
let result = "^(";
result += addWords("", wordlist);
result += ")$";
return result;
}