Обратные ссылки в вид сзади
Можете ли вы использовать обратные ссылки в виде сзади?
Допустим, я хочу split
везде, где позади меня персонаж повторяется дважды.
String REGEX1 = "(?<=(.)\\1)"; // DOESN'T WORK!
String REGEX2 = "(?<=(?=(.)\\1)..)"; // WORKS!
System.out.println(java.util.Arrays.toString(
"Bazooka killed the poor aardvark (yummy!)"
.split(REGEX2)
)); // prints "[Bazoo, ka kill, ed the poo, r aa, rdvark (yumm, y!)]"
С помощью REGEX2
(где обратная ссылка находится в предвидении, вложенном в вид сзади) работает, но REGEX1
выдает эту ошибку во время выполнения:
Look-behind group does not have an obvious maximum length near index 8
(?<=(.)\1)
^
Я полагаю, что это имеет смысл, поскольку в общем случае обратная ссылка может захватывать строку любой длины (хотя, если компилятор регулярных выражений немного умнее, он может определить, что \1
является (.)
в этом случае и, следовательно, имеет конечную длину).
Так есть ли способ использовать обратную ссылку в виде сзади?
А если нет, то можете ли вы обойти это, используя этот вложенный взгляд? Существуют ли другие часто используемые методы?
1 ответ
Похоже, что вы подозреваете, что обратные ссылки обычно не могут быть использованы в Java. Обходное решение, которое вы предложили, делает конечную длину внешнего вида явной и выглядит очень умно для меня.
Я был заинтригован, чтобы узнать, что Python делает с этим регулярным выражением. Python поддерживает только просмотр заданной длины, а не конечную длину, как в Java, но это регулярное выражение имеет фиксированную длину. Я не мог использовать re.split()
напрямую, потому что Питон re.split()
никогда не разбивается на пустое совпадение, но я думаю, что нашел ошибку в re.sub()
:
>>> r=re.compile("(?<=(.)\\1)")
>>> a=re.sub(r,"|", "Bazooka killed the poor aardvark (yummy!)")
>>> a
'Bazo|oka kil|led the po|or a|ardvark (yum|my!)'
Вид сзади совпадает между двумя повторяющимися символами!