Регулярное выражение "И" - PullRequest
       21

Регулярное выражение "И"

4 голосов
/ 21 августа 2009

Я делаю некоторые базовые сопоставления текста из ввода. Мне нужна способность выполнять базовое «И». Для «ЛЮБОГО» я разделяю вводные данные пробелами и соединяю каждое слово с помощью символа «(» |), но я не нашел способа указать регулярному выражению совпадение с любым из слов.

switch (searchOption) {
  case "any":
    inputArray = input.split(" ");
    if (inputArray.length > 1) { input = inputArray.join("|"); }
    text = input;
    break;
  case "all":
    inputArray = input.split(" ");
    ***[WHAT TO DO HERE?]***
    text = input;
    break;
  case "exact":
    inputArray = new Array(input);
    text = input;
    break;
}

Похоже, это должно быть легко.

Ответы [ 4 ]

6 голосов
/ 21 августа 2009

Использование lookahead . Попробуйте это:

if( inputArray.length>1 ) rgx = "(?=.*" + inputArray.join( ")(?=.*" ) + ").*";

В итоге вы получите что-то вроде

(?=.*dog)(?=.*cat)(?=.*mouse).*

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

  • Собака съела кошку, которая съела мышь.
  • Мышь была съедена собакой и кошкой.
  • Большинство кошек любят мышей и собак.

но не

  • Собака у мыши.
  • Кошки и собаки как мыши.

Способ работы состоит в том, что механизм регулярных выражений сканирует текущую точку совпадения (0) в поисках .*dog, первого суб-регулярного выражения (любое число любого символа, за которым следует dog ). Когда он определяет истинность этого регулярного выражения, он сбрасывает точку совпадения (обратно в 0) и переходит к следующему дополнительному регулярному выражению. Итак, сеть состоит в том, что не имеет значения, где находится каждое слово; только то, что каждое слово найдено.

EDIT: @Justin указал, что у меня должен быть трейлинг .*, который я добавил выше. Без этого text.match(regex) работает, но regex.exec(text) возвращает пустую строку соответствия. С завершающим .* вы получите соответствующую строку.

3 голосов
/ 21 августа 2009

Проблема с «и» заключается в следующем: в какой комбинации вы хотите слова? Могут ли они появиться в любом порядке, или они должны быть в указанном порядке? Могут ли они появляться последовательно или между ними могут быть другие слова?

Эти решения сильно влияют на то, что вы делаете (или ищете).

Если вы ищете «A B C» (по порядку, последовательно), выражение будет просто /A B C/. Готово!

Если вы ищете "A foo B bar C", это может быть /A.*?B.*?C/

Если вы ищете «B foo A foo C», вам лучше сделать три отдельных теста для /A/, /B/ и /C/

3 голосов
/ 21 августа 2009

Выполните простой цикл for и найдите каждый термин, например, так:

var n = inputArray.length;
if (n) {
    for (var i=0; i<n; i++) {
        if (/* inputArray[i] not in text */) {
            break;
        }
    }
    if (i != n) {
        // not all terms were found
    }
}
1 голос
/ 21 августа 2009

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

\b(?:(?:(word1)|(word2))(\b.*?)){2,}(?(1)|(?!))(?(2)|(?!))

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

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