Регулярные неупорядоченные совпадения - PullRequest
4 голосов
/ 08 июля 2011

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

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

В булевой логике проверка будет выглядеть так: Если всеOfTheseWords находятся в этом тексте, а atLeastOneOfTheseWords находятся в этом тексте, вернуть true.

Пример
Я ищу (Джон и Барбара) с (счастливым или грустным). Заказ не имеет значения.

"Happy birthday john from barbara" => VALID
"Happy birthday john"              => INVALID

Я просто не могу понять, как упорядочить детали по порядку, любая помощь будет признательна!

Ответы [ 6 ]

4 голосов
/ 08 июля 2011

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

Простым решением будет сбросить все слова в HashSetпроверка точки на наличие слова становится очень быстрой и простой операцией.

3 голосов
/ 08 июля 2011

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

// searching for (john and barbara) with (happy or sad)
"^(?=.*\bjohn\b)(?=.*\bbarbara\b).*\b(happy|sad)\b"

Производительность должна быть сопоставима с полным текстомискать каждое слово в группе allOfTheseWords отдельно.

1 голос
/ 08 июля 2011

В вашем примере это регулярное выражение, которое может помочь вам:

Regex

(?:happy|sad).*?john.*?barbara|
(?:happy|sad).*?barbara.*?john|
barbara.*?john.*?(?:happy|sad)|
john.*?barbara.*?(?:happy|sad)|
barbara.*?(?:happy|sad).*?john|
john.*?(?:happy|sad).*?barbara

выход

happy birthday john from barbara => Matched
Happy birthday john              => Not matched

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

1 голос
/ 08 июля 2011

Если вам действительно нужно регулярное выражение single , то оно будет очень большим и очень медленным из-за возврата.Для вашего конкретного примера (Джон и Барбара) И (Счастливый или Грустный) это начнется так:

\bJohn\b.*?\bBarbara\n.*?\bHappy\b|\bJohn\b.*?\bBarbara\n.*?\bSad\b|......

В конечном итоге вам нужно будет поместить все комбинации в регулярное выражение.Что-то вроде:

JBH, JBS, JHB, JSB, HJB, SJB, BJH, BJS, BHJ, BSJ, HBJ, SBJ

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

0 голосов
/ 08 июля 2011

Если ваши данные относительно постоянны, и вы планируете много искать, использование Apache Lucene обеспечит лучшую производительность.

Используя методы поиска информации, вы сначала проиндексируете все ваши документы / предложения, а затем выполните поиск по вашим словам, в вашем примере вы захотите найти «+ (+ john + barbara) + (sad happy)» [или "(Джон И Барбарар) И (грустный ИЛИ СЧАСТЛИВЫЙ)"]

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

0 голосов
/ 08 июля 2011

Может быть возможно сделать это с помощью регулярного выражения, но это будет настолько сложно, что лучше использовать другой способ (например, с помощью HashSet, как упоминалось в других ответах).

Один из способов сделать это с помощью регулярного выражения - это вычислить все перестановки слов, которые вы ищете, а затем написать регулярное выражение, в котором упоминаются все эти перестановки. С 2 словами будет 2 перестановки, как в (.*foo.*bar.*)|(.*bar.*foo.*) (плюс границы слов), с 3 словами будет 6 перестановок, и довольно скоро число перестановок будет больше, чем ваш входной файл.

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