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