Regex обрабатывает совпадение нулевой длины

1

У меня есть строка с символами * (звездочка) в качестве ввода. Строка считается недействительной, если она имеет две последовательные звездочки. Но есть escape-символ\(обратная косая черта).

Например:

  • "**" (инвалид)
  • "\ **" (действительный)
  • "случай **" (недействительный)
  • "case\**" (действительный)
  • "*\*" (действительный)

Я нахожусь на таком регулярном выражении, которое приводит к некорректному результату:

  1. /[^\\]\*\*/ - java.util.regex.Pattern.compile("/[^\\\\]\\*\\*/")
  2. /([^\\]*?\*\*)|(\*\*)/ - java.util.regex.Pattern.compile("/([^\\\\]*?\\*\\*)|(\\*\\*)/").

Кроме того, я читал о жадных, неохотных и властных количественных значениях здесь http://docs.oracle.com/javase/tutorial/essential/regex/quant.html

Я знаю, что проблема связана с совпадением нулевой длины, но не может создать правильное регулярное выражение.

Теги:
regex-negation
regex-lookarounds

2 ответа

1
Лучший ответ

Вы ищете регулярное выражение, которое будет соответствовать только недействительным строкам? Это должно сделать:

"(?<!\\\\)\\*\\*+"

Он будет соответствовать двум или более звездочкам в строке, а не косой чертой.

EDIT: (?<!foo) thingy называется "негативный внешний вид". Он соответствует любому нулевому месту в строке, которой не сразу предшествует область, соответствующая регулярному выражению внутри круглых скобок (в этом случае "foo" или обратная косая черта в вашем). Сначала я имел это как [^\\\\], что почти одно и то же (в данном случае), за исключением того, что оно соответствует любому символу, отличному от обратного слэша, но не отсутствию символа, как в начале строки в "**".

Существует хорошее подробное описание lookarounds (look-behind и look-ahead), а также множество других "волшебных" регулярных выражений здесь

  • 0
    Пожалуйста, прочитайте, что я сделал, более внимательно.
  • 0
    Неа. Я достаточно осторожен. Я читал, что вы что-то пробовали, и это "дало неверный результат". Если у вас есть дополнительные вопросы или вам нужна дополнительная помощь, пожалуйста, объясните вашу проблему более четко.
Показать ещё 4 комментария
1

Используйте метод string.matches. Это возвращает true для действительных строк.

String s1 = "case**";
String s2 = "case\\**";
System.out.println(s1.matches("(?=.*(\\\\\\*\\*|\\*\\\\\\*)).*"));
System.out.println(s2.matches("(?=.*(\\\\\\*\\*|\\*\\\\\\*)).*"));

Вывод:

false
true

DEMO

  • 0
    Выбранный ответ гораздо проще.
  • 1
    его регулярное выражение соответствует всем недопустимым строкам, а мое - всем допустимым строкам. В этом разница.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню