Home > Software design >  How to ignore order of search terms in regex (ReactJS)?
How to ignore order of search terms in regex (ReactJS)?

Time:10-08

I have a form, through which the user enters input, and I'm trying to make an autocomplete for a form. I'm running regex on a title variable in ReactJS. The regexEscape function si being used to escape the string.

function regexEscape(str) {
    return str.replace(/[-\\^$* ?.()|[\]{}]/g, '\\$&')
  }
if (title.length > 4) {
      matches = movies.filter(movie => {
        let input = regexEscape(title);
        const regex = new RegExp(`${input}`, "gi")
        return movie.match(regex)
      })
    }

Now, suppose user enters "Departed", then it matches with an autocomplete entry that says "Departed, The (2006)", but I want to be able to return "Departed, The (2006)" even if the user has typed "The Departed"

Is that possible? I need to be able to ignore the order of search terms, as well as exclude the comma I think, but I dont know yet how to ignore the order of the words

CodePudding user response:

You can build a pattern that will search for a string containing all words from the title string. It will look like

/^(?=.*The)(?=.*Departed).*/gi

Details:

  • ^ - start of string
  • (?=.*The) - there must be The in the string
  • (?=.*Departed) - there must be Departed in the string
  • .* - any zero or more chars other than line break chars as many as possible (basically, any text till the end of a line).

function regexEscape(str) {
    return str.replace(/[-\\^$* ?.()|[\]{}]/g, '\\$&')
}

const title = "The Departed";
const movies = ["Departed, The (2006)"];

if (title.length > 4) {
  matches = movies.filter(movie => {
    let input = "^(?=.*"   title.split(/\s /).map(x => regexEscape(x)).join(")(?=.*")   ").*";
    const regex = new RegExp(`${input}`, "gi");
    return movie.match(regex);
  });
  console.log(matches)
}

Improving it further, if you plan to only match whole words, like The in The and not in Then, you need adaptive dynamic word boundaries here:

function regexEscape(str) {
    return str.replace(/[-\\^$* ?.()|[\]{}]/g, '\\$&')
}

const title = "The Departed";
const movies = ["Departed, The (2006)", "Then Departed (2006)"];

if (title.length > 4) {
  matches = movies.filter(movie => {
    let input = "^(?=.*(?!\\B\\w)"   title.split(/\s /).map(x => regexEscape(x)).join("(?<!\\w\\B))(?=.*(?!\\B\\w)")   "(?<!\\w\\B)).*";
    const regex = new RegExp(`${input}`, "gi");
    return movie.match(regex);
  });
  console.log(matches)
}

  • Related