Ошибка 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.

Скопировано из Здесь