你能在后视镜中使用反向引用吗?
假设我想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)
^
这种类有意义,我想,因为通常反向引用可以捕获任意长度的字符串(如果正则表达式编译器更聪明一点,它可以确定{{1在这种情况下,\1
是(.)
,因此长度有限。)
那么有没有办法在后视镜中使用反向引用?
如果没有,你可以使用这个嵌套的前瞻来解决它吗?还有其他常用技术吗?
答案 0 :(得分:5)
看起来你的怀疑是正确的,反向引用通常不能用于Java lookbehinds。你提出的解决方法使得lookbehind的有限长度显而易见,对我来说看起来非常聪明。
我很想知道Python对这个正则表达式的作用。 Python只支持固定长度的lookbehind,而不是像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!)'
lookbehind匹配两个重复字符之间的!