Java регулярное выражение: отрицательный взгляд

Я пытаюсь создать два регулярных выражения, которые будут соответствовать URI. Эти URI имеют формат: /foo/someVariableData а также /foo/someVariableData/bar/someOtherVariableData

Мне нужны два регулярных выражения. Каждый должен соответствовать одному, но не другому.

Регулярные выражения, которые я изначально придумал:/foo/.+ а также /foo/.+/bar/.+ соответственно.

Я думаю, что второе регулярное выражение в порядке. Это будет соответствовать только второй строке. Однако первое регулярное выражение соответствует обоим. Итак, я начал играть (впервые) с негативным взглядом. Я разработал регулярное выражение /foo/.+(?!bar) и установите следующий код, чтобы проверить это

public static void main(String[] args) {
    String shouldWork = "/foo/abc123doremi";
    String shouldntWork = "/foo/abc123doremi/bar/def456fasola";
    String regex = "/foo/.+(?!bar)";
    System.out.println("ShouldWork: " + shouldWork.matches(regex));
    System.out.println("ShouldntWork: " + shouldntWork.matches(regex));
}

И, конечно же, они оба решают true,

Кто-нибудь знает, что я делаю не так? Мне не нужно обязательно использовать Negative lookahead, мне просто нужно решить проблему, и я думаю, что отрицательный взгляд может быть одним из способов сделать это.

Спасибо,

1 ответ

Решение

Пытаться

String regex = "/foo/(?!.*bar).+";

или возможно

String regex = "/foo/(?!.*\\bbar\\b).+";

чтобы избежать сбоев на таких путях, как /foo/baz/crowbars что я предполагаю, что вы хотите, чтобы это регулярное выражение соответствовало.

Объяснение: (без двойной обратной косой черты, требуемой для строк Java)

/foo/ # Match "/foo/"
(?!   # Assert that it's impossible to match the following regex here:
 .*   #   any number of characters
 \b   #   followed by a word boundary
 bar  #   followed by "bar"
 \b   #   followed by a word boundary.
)     # End of lookahead assertion
.+    # Match one or more characters

\b"привязка границы слова" соответствует пустому пространству между буквенно-цифровым символом и не алфавитно-цифровым символом (или между началом / концом строки и символом-цифрой). Таким образом, это соответствует до b или после r в "bar", но он не соответствует между w а также b в "crowbar",

Подсказка: взгляните на http://www.regular-expressions.info/ - отличный учебник по регулярным выражениям.

Другие вопросы по тегам