Home > Enterprise >  How to match a regular expression against another regular expression in javascript?
How to match a regular expression against another regular expression in javascript?

Time:07-05

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'
))

  • Related