How can I emulate the SQL keyword LIKE
in JavaScript?
For those of you who don't know what LIKE
is, it's a very simple regex which only supports the wildcards %
, which matches 0 or more characters, and _
which matches exactly one character.
However, it's not just possible to do something like:
var match = new RegEx(likeExpr.replace("%", ".*").replace("_", ".")).exec(str) != null;
...because the pattern might contain dots, stars and any other special regex characters.
An old question but there are actually no good answers here. TSQL LIKE expressions can contain square-bracket escaped sections that are already almost valid regular expressions and allow for matching %
and _
. E.g.:
'75%' LIKE '75[%]'
'[foo]' LIKE '[[]foo]' -- ugh
Here's my function to convert a LIKE expression into a RegExp. The input is split into square-bracket and non-square-bracket sections. The square-bracket sections just need backslash escaping and the non-square-bracket sections are fully escaped while the %
and _
directives are converted to regular expressions.
const likeRegExp = (expression, caseSensitive = false) =>
new RegExp(`^${
expression.split(/(\[.+?\])/g)
.map((s, i) => i % 2 ?
s.replace(/\\/g, '\\\\') :
s.replace(/[-\/\\^$*+?.()|[\]{}%_]/g, m => {
switch(m) {
case '%': return '.*';
case '_': return '.';
default: return `\\${m}`;
}
})
).join('')
}$`, caseSensitive ? '' : 'i');
What you have will work as long as you first escape the regex characters in your pattern. Below is one example from Simon Willison’s blog:
RegExp.escape = function(text) {
if (!arguments.callee.sRE) {
var specials = [
'/', '.', '*', '+', '?', '|',
'(', ')', '[', ']', '{', '}', '\\'
];
arguments.callee.sRE = new RegExp(
'(\\' + specials.join('|\\') + ')', 'g'
);
}
return text.replace(arguments.callee.sRE, '\\$1');
}
You could then implement your code as:
likeExpr = RegExp.escape(likeExpr);
var match = new RegEx(likeExpr.replace("%", ".*").replace("_", ".")).exec(str) != null;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With