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 xamplefunction, которому не предшествует "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