регулярное выражение javascript - сопоставить несколько поисковых терминов, игнорируя их порядок - PullRequest
5 голосов
/ 10 января 2012

Я хотел бы найти все совпадения заданных строк (разделенных пробелами) в строке.(Как, например, окно поиска iTunes работает).

То есть, например, " ab de " и " de ab " вернут true на " abcde"(также" bc ea"или любой заказ должен возвращать true)

Если я заменю пробел символом подстановки," ab * de "будетверните true в " abcde ", но не в "de * ab".[Я использую *, а не синтаксис Regex только для этого объяснения]

Я не смог найти никакого чистого решения Regex для этого.Единственное решение, которое я могу придумать, - это разделить поисковый запрос и запустить несколько регулярных выражений.

Можно ли найти чистое выражение регулярного выражения, которое охватит все эти параметры?

Ответы [ 7 ]

5 голосов
/ 01 августа 2016

Возвращает true, когда все части (разделенные на , или ' ') searchString встречаются в текстеВ противном случае возвращается false.

filter(text, searchString) {
    const regexStr = '(?=.*' + searchString.split(/\,|\s/).join(')(?=.*') + ')';
    const searchRegEx = new RegExp(regexStr, 'gi');
    return text.match(searchRegEx) !== null;
}
4 голосов
/ 10 января 2012

Чередования нечувствительны к порядку:

"abcde".match(/(ab|de)/g); // => ['ab', 'de']
"abcde".match(/(de|ab)/g); // => ['ab', 'de']

Так что, если у вас есть список слов для сравнения, вы можете создать регулярное выражение с чередованием на лету, например:

function regexForWordList(words) {
  return new RegExp('(' + words.join('|') + ')', 'g');
}
'abcde'.match(['a', 'e']); // => ['a', 'e']
4 голосов
/ 10 января 2012

Я почти уверен, что вы можете придумать регулярное выражение, чтобы делать то, что вы хотите, но это может быть не самый эффективный подход.

Например, шаблон регулярного выражения (?=.*bc)(?=.*e)(?=.*a) будет соответствовать любой строке, содержащей bc, e, и a.

var isMatch = 'abcde'.match(/(?=.*bc)(?=.*e)(?=.*a)/) != null; // equals true

var isMatch = 'bcde'.match(/(?=.*bc)(?=.*e)(?=.*a)/) != null; // equals false

Вы могли бы написать функцию для динамического создания выражения, основанного на ваших поисковых терминах, но вопрос о том, является ли это наилучшим способом выполнения того, что вы делаете, - другой вопрос.

3 голосов
/ 10 января 2012

Попробуйте это:

var str = "your string";
str = str.split( " " );
for( var i = 0 ; i < str.length ; i++ ){
    // your regexp match
}
2 голосов
/ 15 января 2016

Это скрипт, который я использую - он работает также с одиночным словом searchStrings

var what="test string with search cool word";
var searchString="search word";
var search = new RegExp(searchString, "gi"); // one-word searching

// multiple search words
if(searchString.indexOf(' ') != -1) {

    search="";
    var words=searchString.split(" ");

    for(var i = 0; i < words.length; i++) {

        search+="(?=.*" + words[i] + ")";

    }

    search = new RegExp(search + ".+", "gi");

}

if(search.test(what)) {

    // found

} else {

    // notfound

}
1 голос
/ 10 января 2012

Я предполагаю, что вы подходите слова или части слов. Вы хотите, чтобы термины поиска, разделенные пробелами, ограничивали результаты поиска, и, похоже, вы намереваетесь возвращать только те записи, в которых есть все слова, предоставленные пользователем. И вы намерены использовать подстановочный знак * для обозначения 0 или более символов в соответствующем слове.

Например, если пользователь ищет слова term1 term2 , вы намереваетесь вернуть только те элементы, которые имеют оба слова term1 и term2. Если пользователь ищет слово term *, оно будет соответствовать любому слову, начинающемуся с term.

Существуют подходящие регулярные выражения, которые эквивалентны этому языку поиска и могут быть сгенерированы из него.

Простой пример, слово term, может быть подтверждено в регулярном выражении путем преобразования в \bterm\b. Но два или более слова, которые должны совпадать в любом порядке, требуют предварительных утверждений. Используя расширенный синтаксис, эквивалентное регулярное выражение:

(?= .* \b term1 \b )
(?= .* \b term2 \b )

Подстановочный знак звездочки может быть указан в регулярном выражении с классом символов, за которым следует звездочка. Класс символов определяет, какие буквы вы считаете частью слова. Например, вы можете обнаружить, что [A-Za-z0-9]* соответствует требованиям.

Короче говоря, вы можете быть удовлетворены, если преобразуете такие выражения, как:

foo ba* quux

до:

(?= .* \b foo            \b )
(?= .* \b ba[A-Za-z0-9]* \b )
(?= .* \b quux           \b )

Это простой вопрос поиска и замены. Но будьте осторожны, чтобы очистить входную строку, чтобы избежать атак инъекций путем удаления знаков препинания и т. Д.

0 голосов
/ 10 января 2012

Я думаю, что вы можете лаять не то дерево с помощью RegEx. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}}}}}1009 * здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...