Подтвердить что ты не робот

Java regex: отрицательный просмотр

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

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

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

Я думаю, что второе регулярное выражение прекрасно. Он будет соответствовать только второй строке. Однако первое регулярное выражение соответствует обоим. Итак, я начал играть (в первый раз) с негативным взглядом. Я разработал regex /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.

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

Спасибо,

4b9b3361

Ответ 1

Try

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

или, возможно,

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

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

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

/foo/ # Match "/foo/"
(?!   # Assert that it 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, "привязка границы слова" совпадает с пустым пространством между буквенно-цифровым символом и не-буквенно-цифровым символом (или между началом/концом строки и символом alnum). Поэтому он соответствует до b или после r в "bar", но он не соответствует между w и b в "crowbar".

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