I want to see whether there are any matches between my two regular expressions. To do this, I just perform a .test
against each other, and if one of them matches true
, I consider them to be matched.
const toRegex = (str) =>
new RegExp(
'^'
str
.replace(/[\-\[\]\/\{\}\(\)\ \.\\\^\$\|]/g, '\\$&')
.replace(/\*/g, '.*')
.replace(/\?/g, '.')
'$',
);
const compare = (
stringA,
stringB,
) => {
return (
toRegex(stringA).test(stringB) ||
toRegex(stringB).test(stringA)
);
};
For wildcards at the end of the text, it's working like a charm.
const stringA = 'john:alex:*';
const stringB = 'john:*';
console.log('compare', compare(stringA, stringB)) // true
However, I was unable to make the function work if there were extra words at the end. I want my function to treat the stringA which contains a wildcard, as equal to the word doe
in the stringB.
const stringA = 'john:alex:*';
const stringB = 'john:*:doe';
console.log('compare', compare(stringA, stringB)) // false
By comparing two separate regular expressions, how can I accomplish this? I would appreciate some help with this.
CodePudding user response:
Assuming *
means "any number of characters", your equivalence relation can be written as
- if A is empty, then true if B is empty too, otherwise false
- split A and B into a head (=first char) and a tail (the rest)
- if heads are equal, then compare both tails
- if A's head is *, then try A's tail against B, then B.slice(1), then B.slice(2) etc...
- if B's head is *, swap A and B
- otherwise, false
function isEq(a, b) {
if (!a || !b)
return a === b;
let [headA, tailA] = [a[0], a.slice(1)]
let [headB, tailB] = [b[0], b.slice(1)]
if (headA === headB)
return isEq(tailA, tailB);
if (headA === '*') {
for (let i = 0; i <= b.length; i )
if (isEq(tailA, b.slice(i)))
return true;
return false;
}
if (headB === '*')
return isEq(b, a)
return false;
}
console.log(isEq(
'john:alex:*',
'john:*:doe'
))
console.log(isEq(
'john:alex:*',
'john:*'
))
console.log(isEq(
'john:*:X',
'john:*:Y'
))