Можно ли использовать обратные ссылки в lookbehind?
Скажем, я хочу 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
(где обратная ссылка находится в предвидении, вложенном в lookbehind), работы, но REGEX1
дает эту ошибку во времени выполнения:
Look-behind group does not have an obvious maximum length near index 8
(?<=(.)\1)
^
Этот вид имеет смысл, я предполагаю, потому что в целом обратная ссылка может получить строку любой длины (если regex компилятор немного более умен, тем не менее, это могло бы определить это \1
(.)
в этом случае, и поэтому имеет конечную длину).
Так существует ли способ использовать обратную ссылку в lookbehind?
И если нет, можно ли всегда работать вокруг этого с помощью этого вложенного предвидения? Есть ли другие наиболее часто используемые методы?
Похоже, ваше подозрение верно, что обратные ссылки, как правило, не могут использоваться в обратных ссылках Java. Предложенный вами обходной путь делает явной конечную длину ретроспективного просмотра и кажется мне очень умным.
Я был заинтригован, узнав, что Python делает с этим регулярным выражением. Python поддерживает только ретроспективный просмотр фиксированной длины, а не конечной длины, как Java, но это регулярное выражение имеет фиксированную длину. Я не мог использовать re.split ()
напрямую, потому что Python 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!)'
Поиск назад соответствует между двумя повторяющимися символами!