Почему этот отрицательный взгляд с регулярным выражением фиксированной длины не работает?

Я пытаюсь сопоставить один '1' в списке номеров, разделенных пробелами. Вот пример кода:

public class RegexTester {
  public static void main(String[] args) {

    String test1 = "1 2";
    String test2 = "2 1 2";
    String test3 = "2 11 2";

    String regex = "(?<!\\d)1(?!\\d)";

    System.out.println("Matches 1: " + test1.matches(regex));
    System.out.println("Matches 2: " + test2.matches(regex));
    System.out.println("Matches 3: " + test3.matches(regex));
  }
}

Выход:

Matches 1: false
Matches 2: false
Matches 3: false

Но должно быть (имо):

Matches 1: true
Matches 2: true
Matches 3: false

Lookbehind имеет фиксированную длину, поэтому я не понимаю, почему это регулярное выражение не совпадает. Я ценю это, если вы знаете, почему и / или можете предоставить альтернативное рабочее выражение для этого случая.

Спасибо.

1 ответ

Решение

Ваше регулярное выражение верно. Проблема в том, что matches Метод проверяет, может ли вся входная строка соответствовать регулярному выражению, а не содержит ли она подстроку, которой может соответствовать регулярное выражение.

Может быть, использовать find() метод из Matcher класс вместо.

String test1 = "1 2";
String test2 = "2 1 2";
String test3 = "2 11 2";

String regex = "(?<!\\d)1(?!\\d)";
Pattern p = Pattern.compile(regex);

System.out.println("Matches 1: " + p.matcher(test1).find());
System.out.println("Matches 2: " + p.matcher(test2).find());
System.out.println("Matches 3: " + p.matcher(test3).find());

Выход:

Matches 1: true
Matches 2: true
Matches 3: false

Обновить:

Если вам действительно нужно использовать matches тогда вы можете просто добавить .* в начале и в конце вашего регулярного выражения, так что части, кроме требуемого, также могут быть использованы регулярным выражением.

String regex = ".*(?<!\\d)1(?!\\d).*";

System.out.println("Matches 1: " + test1.matches(regex));
System.out.println("Matches 2: " + test2.matches(regex));
System.out.println("Matches 3: " + test3.matches(regex));

Выход:

Matches 1: true
Matches 2: true
Matches 3: false
Другие вопросы по тегам