2010-12-17 3 views
0

Я хочу реализовать функцию соответствия регулярных выражений в javascript, которая соответствует одному или нескольким ключевым словам в тексте. Каждое ключевое слово должно быть найдено в любом порядке. Ключевые слова вводятся пользователем.Соответствие ключевого слова Regex

Вот где я нахожусь:

\b(smart.*\bwork.*|work.*\bsmart.*) 
  • спички "trying to work smarter"
  • но не "trying to work" or "trying to be smart"

Проблема с этим подходом, я должен создавать различные упорядоченные перестановки (что-то подобное в любом случае) из набора ключевых слов.

Так вопросы:

  1. Если простой RegEx-единственный способ? (Т.е. "\b(smart.*|work.*)<magic:all,anyorder>", что будет убедиться, что все ключевые слова будут найдены, и в любом порядке)
  2. Если нет - вы можете предложить яваскрипта реализацию перестановок массива (так что с [1,2,3] он генерирует [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]])

UPDATE

Предназначен для поиска набора строк (10-50 строк) на стороне клиента (в браузере).

+4

Я бы не рекомендовал регулярное выражение, когда дело доходит до «этих ключевых слов в любом порядке с чересстрочной приемлемой». Я бы рекомендовал `indexOf()` для каждого ключевого слова; это будет стоить намного меньше, чем потенциально сложное регулярное выражение. – BeemerGuy 2010-12-17 00:32:36

+0

Трудно понять, что вы пытаетесь сделать. Это не какой-то рандомизатор спама? – 2010-12-17 00:38:46

+0

Ваш второй вариант звучит как кошмар производительности, если вы собираетесь использовать его для создания группы RegEx и протестировать их все. – 2010-12-17 00:48:19

ответ

5

Моего друг ответ Хуана будет работать очень хорошо, если пользователь не ищет маленькие слова, которые могут появиться в более длинных словах. В этом случае вам нужно вернуться к регулярным выражениям. Вы можете использовать гибридный подход, который использует только RE, когда строка найдена. Что-то вроде:

String.prototype.containsAll = function(){ 
    for (var i=0; i < arguments.length; i++) { 

     if (this.indexOf(arguments[i]) > -1) { 
      // test with regular expressions 
      var re = new RegExp('\\b' + escapeRe(arguments[i]) + '\\b') 
      if (!re.test(this)) { 
       return false; 
      } 
     } else { 
      return false 
     } 
    } 
    return true; 

    function escapeRe(re) { 
     return re.replace(/[$.*+?()\[\]\\^]/g, function(chr) { 
      return '\\' + chr; 
     }); 
    } 
} 

Никогда не тестировалось, особенно битбера escapeRe.

1

Просто потому, что BeemerGuy не размещал его в качестве ответа. Но кредит идет к нему. Там нет RegEx, который может делать то, что вы хотите, гораздо проще создать метод, который использует indexOf. Мои тесты производительности показывают, что вы всегда должны предпочесть indexOf над RegEx, если это возможно.

function containsAll(searchString /*, word, word,...*/) { 
    for (var i=1; i < arguments.length; i++) { 
    if (searchString.indexOf(arguments[i]) == -1) { 
     return false; 
    } 
    } 
    return true; 
} 

или, если вы не против изменения String.prototype

String.prototype.containsAll = function(){ 
    for (var i=0; i < arguments.length; i++) { 
    if (this.indexOf(arguments[i]) == -1) { 
     return false; 
    } 
    } 
    return true; 
}