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
. Не следует ли его выбросить?
3 ответа:
Посмотрите, чему он соответствует:
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+$
Я предпочитаю второй подход, так как он означает, что шаблон сам определяет свою область соответствия, а не область, определяемую его использованием. Однако это всего лишь вопрос предпочтения.
Обратите внимание на две вещи:
Вы используете
find()
, который возвращает true для подстроки.Из-за вышесказанного "функция" совпадает, поскольку ей не предшествует "функция".
Вся строка никогда бы не совпала, потому что ваше регулярное выражение не совпадало. включите пробелы.Вместо этого используйте
Mathcher#matches()
или^
и$
якоря с отрицательным lookahead:Pattern pat = Pattern.compile("^(?!function)[\\w\\s]+$"); // added \s for whitespaces Matcher mat = pat.matcher("function example"); System.out.println(mat.find()); // false