Ошибка Java regex - группа Look-behind не имеет очевидной максимальной длины
Я получаю эту ошибку:
java.util.regex.PatternSyntaxException: Look-behind group does not have an
obvious maximum length near index 22
([a-z])(?!.*\1)(?<!\1.+)([a-z])(?!.*\2)(?<!\2.+)(.)(\3)(.)(\5)
^
Я пытаюсь сопоставить COFFEE
, но не BOBBEE
.
Я использую java 1.6.
Ответы
Ответ 1
Java не поддерживает переменную длину.
В этом случае, кажется, вы можете легко игнорировать его (при условии, что весь ваш ввод - одно слово):
([a-z])(?!.*\1)([a-z])(?!.*\2)(.)(\3)(.)(\5)
Оба lookbehind ничего не добавляют: первый утверждает, по крайней мере, два символа, в которых у вас был только один, а второй проверяет второй символ, отличный от первого, который уже был покрыт (?!.*\1)
.
Рабочий пример: http://regexr.com?2up96
Ответ 2
Чтобы избежать этой ошибки, вы должны заменить +
на область типа {0,10}
:
([a-z])(?!.*\1)(?<!\1.{0,10})([a-z])(?!.*\2)(?<!\2.{0,10})(.)(\3)(.)(\5)
Ответ 3
Java делает шаг вперед, позволяя конечное повторение. Вы по-прежнему не можете использовать звезду или плюс, но вы можете использовать знак вопроса и фигурные скобки с указанным максимальным параметром. Java определяет минимальную и максимально возможную длину lookbehind.
Вид в регулярном выражении (?<!ab{2,4}c{3,5}d)test
имеет 6 возможных длин. Длина может составлять от 7 до 11 символов. Когда Java (версия 6 или более поздняя версия) пытается сопоставить lookbehind, она сначала отменяет минимальное количество символов (7 в этом примере) в строке и затем оценивает регулярное выражение внутри lookbehind, как обычно, слева направо. Если это не удается, Java отбрасывает еще один символ и снова пытается. Если lookbehind продолжает терпеть неудачу, Java продолжает отступать, пока lookbehind не будет соответствовать, или отменил максимальное количество символов (11 в этом примере). Этот повторный шаг назад по предметной строке убивает производительность при увеличении числа возможных длин объекта lookbehind. Имейте это в виду. Не выбирайте произвольно большое максимальное количество повторений для работы вокруг отсутствия бесконечных кванторов внутри lookbehind. В Java 4 и 5 есть ошибки, которые вызывают зависание с переменными или кванторами переменных, если они преуспевают в некоторых ситуациях. Эти ошибки были исправлены на Java 6.
Скопировано из Здесь