Regex to match partial words (JavaScript)
You got:
"n univ av"
You want:
"\bn.*\buniv.*\bav.*"
So you do:
var regex = new RegExp("n univ av".replace(/(\S+)/g, function(s) { return "\\b" + s + ".*" }).replace(/\s+/g, ''), "gi");
Voilà!
But I'm not done, I want my bonus points. So we change the pattern to:
var regex = new RegExp("n univ av".replace(/(\S+)/g, function(s) { return "\\b(" + s + ")(.*)" }).replace(/\s+/g, ''), "gi");
And then:
var matches = regex.exec("N University Ave");
Now we got:
- matches[0] => the entire expression (useless)
- matches[odd] => one of our matches
- matches[even] => additional text not on the original match string
So, we can write:
var result = '';
for (var i=1; i < matches.length; i++)
{
if (i % 2 == 1)
result += '<b>' + matches[i] + '</b>';
else
result += matches[i];
}
function highlightPartial(subject, search) {
var special = /([?!.\\|{}\[\]])/g;
var spaces = /^\s+|\s+/g;
var parts = search.split(" ").map(function(s) {
return "\b" + s.replace(spaces, "").replace(special, "\\$1");
});
var re = new RegExp("(" + parts.join("|") + ")", "gi");
subject = subject.replace(re, function(match, text) {
return "<b>" + text + "</b>";
});
return subject;
}
var result = highlightPartial("N University Ave", "n univ av");
// ==> "<b>N</b> <b>Univ</b>ersity <b>Av</b>e"
Side note - this implementation does not pay attention to match order, so:
var result = highlightPartial("N University Ave", "av univ n");
// ==> "<b>N</b> <b>Univ</b>ersity <b>Av</b>e"
If that's a problem, a more elaborate sequential approach would become necessary, something that I have avoided here by using a replace()
callback function.