Java RegEx отрицательный lookbehind
У меня есть следующий код Java:
Pattern pat = Pattern.compile("(?<!function )\\w+");
Matcher mat = pat.matcher("function example");
System.out.println(mat.find());
Почему mat.find()
возвращает true? Я использовал отрицательный lookbehind, а example
- function
. Не следует ли отбрасывать его?
Ответы
Ответ 1
Посмотрите, что он соответствует:
public static void main(String[] args) throws Exception {
Pattern pat = Pattern.compile("(?<!function )\\w+");
Matcher mat = pat.matcher("function example");
while (mat.find()) {
System.out.println(mat.group());
}
}
Вывод:
function
xample
Итак, сначала он находит function
, которому не предшествует "function
". Затем он находит xample
, которому предшествует function e
и, следовательно, не "function
".
Предположительно, вы хотите, чтобы шаблон соответствовал тексту целого, а не просто находил совпадения в тексте.
Вы можете сделать это с помощью Matcher.matches()
, или вы можете изменить шаблон, чтобы добавить стартовые и конечные привязки:
^(?<!function )\\w+$
Я предпочитаю второй подход, так как это означает, что сам шаблон определяет свою область соответствия, а не область, определяемую ее использованием. Это только вопрос предпочтения.
Ответ 2
В вашей строке есть слово "функция", которое соответствует \w +, и ему не предшествует "функция".
Ответ 3
Обратите внимание на две вещи:
-
Вы используете find()
, который возвращает true для соответствия подстроки.
-
Из-за вышеизложенного, "функция" соответствует, так как ей не предшествует "функция".
Вся строка никогда не будет соответствовать, потому что ваше регулярное выражение не
включают пробелы.
Используйте привязки Mathcher#matches()
или ^
и $
вместо отрицательного вида:
Pattern pat = Pattern.compile("^(?!function)[\\w\\s]+$"); // added \s for whitespaces
Matcher mat = pat.matcher("function example");
System.out.println(mat.find()); // false