2009-08-21 2 views
4

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

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; 
} 

Кажется, должно быть легко.

+0

Вы имеете в виду «соответствовать всем словам»? – wds

ответ

6

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

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

Вы будете в конечном итоге с чем-то вроде

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

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

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

Но не

  • Собака на мышь.
  • Кошки и собаки, как мыши.

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

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

+0

Nice трюк, счет. Я на самом деле не думал, что регулярные выражения javascript поддерживают lookaheads. –

+0

Не должно быть '. *' В конце шаблона? Таким образом, полный шаблон будет «(? =. * Dog) (? =. * Cat) (? =. * Mouse). *'? Взгляды нуждаются в чем-то, над чем можно работать. –

+0

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

3

Сделайте простой 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 
    } 
} 
+0

Но, судя по логике этого метода, webwires хочет, чтобы переменная 'text' использовала одно регулярное выражение. Не то чтобы я мог думать о том, как это сделать! – butterchicken

+0

Это должно было бы генерировать каждую возможную перестановку, и это * n * !. – Gumbo

+0

вот как я в конечном итоге справился с этим (хотя с jQuery) ... просто подумал, что, возможно, был более простой способ. – webwires

3

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

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

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

Если вы ищете «бар Foo B C» может быть /A.*?B.*?C/

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

1

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

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

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

Смежные вопросы