pol*_*nts 11 java regex backreference 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!)]"
Run Code Online (Sandbox Code Playgroud)
使用REGEX2(其中反向引用嵌套在lookbehind中的前瞻)可以工作,但REGEX1在运行时会出现此错误:
Look-behind group does not have an obvious maximum length near index 8
(?<=(.)\1)
^
Run Code Online (Sandbox Code Playgroud)
这个排序是有意义的,我想,因为在一般的反向引用可以捕捉任何长度的字符串(如果正则表达式编译器是有点聪明,但是,它可以判断\1是(.)在这种情况下,因此具有有限的长度).
那么有没有办法在后视镜中使用反向引用?
如果没有,你可以使用这个嵌套的前瞻来解决它吗?还有其他常用技术吗?
看起来你的怀疑是正确的,反向引用通常不能用于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!)'
Run Code Online (Sandbox Code Playgroud)
两个重复字符之间的lookbehind匹配!