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 beThe
in the string(?=.*Departed)
- there must beDeparted
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)
}