2014-02-18 4 views
4

Я безуспешно пытаюсь найти решение этой проблемы: Чтобы найти Java-регулярное выражение, которое может распознать строку, содержащую одно слово, и не содержащее другое слово.Regex: содержит слово, не содержит другого слова

Чтобы быть более ясным, в качестве примера давайте проверим, содержит ли мое предложение «метод» и не содержит «эффективных» целых слов (что означает, что оно не должно быть частью другого слова). Регулярное выражение согласовань должна вернуться, например,:.

This method was efficient.  false (contains "method", but contains "efficient") 
This method was unefficient. true (cont. "method" doesn't cont. "efficient") 
This method was simple.   true (cont. "method" doesn't cont. "efficient") 
This routine is efficient  false (cont. "efficient" but no "method") 

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

(method)(?!.*efficient.*)  Almost there, but "unefficient" also triggers. 
(method)(?!.* efficient .*) No. Now " method " doesn't trigger anymore. 
((.*method.*)(?!.*efficient.*)) No. the absence of "efficient" doesn't trigger. 

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

(.*\bmethod\b.*)(?!.*efficient.*) 

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

Я использую http://www.regular-expressions.info/refquick.html в качестве справочного сайта и http://regexpal.com/ для тестирования.

Спасибо! D.

+2

Почему вы не используете ['String # contains'] (http://docs.oracle.com/javase/7/docs/api/java /lang/String.html#contains(java.lang.CharSequence))? – Maroun

+0

Хороший вопрос. Я хочу выполнить проверку набором таблиц сложных синтаксических строк. Например (в метаязыке): (+ word1) (- word2) -> Action1; ((+ word1) (- word3) || (word4)) -> Action2; – donnadulcinea

+0

Что сказал Марун или просто «(? S)^(? =. * \\ bmethod \\ b) (?!. * \\ эффективный \\ b)'. '(? s)' заключается в том, чтобы установить модификатор 's' в соответствие с символами новой строки с' .' – HamZa

ответ

1

Я просто хочу уточнить свой первый подход ((method)(?!.*efficient.*)).

Вы уже сказали Almost there, так почему бы не воспользоваться этим подходом немного дальше? Я просто добавил слово-граница \b перед тем efficient, поэтому он не будет исключать unefficient:

^.+(method)(?!.*\befficient.*) 

demo @ regex101


Теперь есть одна вещь:

this is an efficient method 

все равно будет нежелательную матч (Я полагаю).

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

^(?!.*\befficient.*).*(method) 

demo @ regex101


Для того, чтобы соответствовать efficient именно вы должны добавить еще одно слово-границу, в противном случае он будет соответствовать на efficients, тоже:

^(?!.*\befficient\b).*(\bmethod) 

Если вы хотите сделать method точное совпадение, просто добавьте еще одну границу после нее. Пока это будет соответствовать methods.

+0

Спасибо вам за ответ. Я немного уточнил это: ^(?!.*\befficient.*).+(\bmethod)(?!.*\befficient.*) так что также «метод» должен быть точным совпадением. Проблема остается за окончанием.

this are efficients method
должно быть правдой потому что слово эффективное не является точным совпадением. Я думаю, что самым простым решением для моих анализов является разделение наборов правил и их проверка. Я попробую позже, когда мой мозг покоится некоторое время! (---> Извините, четыре пробела у нас здесь не работают!) – donnadulcinea

+0

@donnadulcinea Если вы хотите исключить «эффективность», значит, это действительно соответствует только «эффективному», тогда вы можете просто добавить другое слово- граница после 'effective':' \ effective \ b'. Таким образом, все ваше регулярное выражение будет выглядеть следующим образом: '^ (?!. * \ Effective \ b. *). + (\ Bmethod) (?!. * \ Effective \ b. *)' –

+0

Я только что попробовал раньше, и он сделал Я работаю, может быть, я немного ошибся. Твоя работа !!! Спасибо @Basti M. Поскольку заказ все еще считается, я думаю, что не могу использовать регулярное выражение для такого разбора (у меня будут сложные правила), но это был интересный урок. – donnadulcinea

2

Как насчет:

^(?=.*\bmethod\b)(?!.*\befficient\b) 
1

Вы можете сделать следующее:

Pattern p = Pattern.compile("(\\bmethod\\b)?.*(\\befficient\\b)?"; 
Matcher m = p.matcher("The method is unefficient."); 
if (m.find() 
    && ((m.group(1) == null) != (m.group(2) == null))) { 
    // found exactly 1 word. 
    ... 
} 
else // found 0 or 2 words. 

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

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