Недавно, мне понадобилось осуществлять поиск по массиву объектов(со строковыми полями). В JavaScript, сложный поиск осуществляется с помощью регулярных выражений, для того чтобы искать в контексте объекта String, есть метод(прототип) match().
Но так как задача похожа на поиск по БД, то мне захотелось использовать синтаксис поиска MySQL функции like() - она очень удобна, когда не нужно явно применять поиск по сложному регулярному выражению. Например: поиск строк начинающихся, заканчивающихся какой-то подстрокой или включают подстроку (что совпадало с моей задачей).
Плюс ко всему - нужно уметь динамически генерировать это условие. Конечно, в JavaScript легко создать регулярное выражение из строки с помощью конструктора new RegExp(pattern, attrs), но это не так красиво как использование like. Потому я расширил прототип String этим методом. Внутри он таки использует регулярные выражения, но от программиста это скрыто, и пользоваться этим удобно и интуитивно всем кто знает SQL.
Алгоритм еще может оптимизироваться, но уже сейчас он работает довольно быстро.
String.prototype.like = function(s) {
if(undefined==s || typeof(s)!='string') return false;
function replacer(str, p1, p2) {
if(p1=='\\') return p2;
if(p2=='%') return p1+'.+';
return p1+'\\w';
}
var pattern = "^"+s.replace(/(.|^)([%_])/gm, replacer)+'$';
var re = new RegExp(pattern, 'mg');
if(this.match(re)) return true;
return false;
};
Пример использования:
var s = "Test string";
console.log( s.like("%ing") );
// True
console.log( s.like("%in") );
// False
console.log( s.like("%in_") );
// True
console.log( s.like("Test%") );
// True
console.log( s.like("%str%") );
// True
console.log( s.like("%spr%") );
// False
console.log( s.like("%s_r%") );
// True
Для того чтобы использовать символы "%", "_" в строке поиска, их нужно экранировать двумя бэк-слешами "\\%".