请注意,这个问题是在Julia的背景下,因此(据我所知)是PCRE。
假设你有一个这样的字符串:
"sssppaaasspaapppssss"
并且你想单独匹配字符串末尾的重复字符(在我们的字符串的情况下,四个" s"字符 - 也就是说,所以matchall给出[&# 34; s"," s"," s"," s"],而不是[" ssss"])。这很简单:
r"(.)(?=\1*$)"
它实际上是微不足道的(并且很容易使用 - replace(r"(.)(?=\1*$)","hell","k")
会给"hekk"
而replace(r"(.)(?=\1*$)","hello","k")
会给"hellk"
)。并且可以通过将点切换为更复杂的点来重复模式:
r"(\S+)(?=( \1)*$)"
例如,将独立匹配" abc"的最后三个实例。在"abc abc defg abc h abc abc abc"
。
然后导致问题...如何匹配字符串 start 的重复字符或模式?具体来说,以上面使用的方式使用正则表达式。
显而易见的方法是将上述正则表达式的方向反转为r"(?<=^\1*)(.)"
- 但PCRE / Julia不允许lookbehinds具有可变长度(除非它是固定变量,像(?<=ab|cde)
),因此抛出一个错误。接下来的想法是使用&#34; \ K&#34;作为r"^\1*\K(.)"
的内容,但这只能匹配第一个字符(可能是因为它&#34;进展&#34;匹配后,不再匹配插入符号。)
为了清楚起见:我正在寻找一个正则表达式,例如,会导致
replace("abc abc defg abc h abc abc abc",<regex here>,"hello")
制造
"hello hello defg abc h abc abc abc"
正如您所看到的,它正在取代每个&#34; abc&#34;从#34;你好&#34;开始,但直到第一次不匹配。我在上面提供的反面文章在字符串的另一端执行此操作:
replace("abc abc defg abc h abc abc abc",r"(\S+)(?=( \1)*$)","hello")
产生
"abc abc defg abc h hello hello hello"
答案 0 :(得分:8)
您可以使用匹配上一个匹配后位置或字符串开头位置的\G
锚点。通过这种方式,您可以确保从字符串开头到最后一次出现的结果的连续性:
\G(\S+)( (?=\1 ))?
或者能够匹配到字符串的结尾:
\G(\S+)( (?=\1(?: |\z)))?
答案 1 :(得分:4)
对于PCRE型发动机,遗憾的是没有锡就无法做到这一点 可变长度的后视。
无法实现纯粹的解决方案
没有 \G
锚定技巧可以实现此目的。
这就是\ G锚无法奏效的原因。
使用锚点,唯一的保证就是最后一场比赛 导致匹配,其中前向重叠被检查为相等 到目前的比赛。
因此,您只能从头开始全局匹配副本的 N-1 。
这是一个证据:
正则表达式:
# (?:\G([a-c]+)(?=\1))
(?:
\G
( [a-c]+ ) # (1)
(?=
\1
)
)
输入:
abcabcabcbca
输出:
** Grp 0 - ( pos 0 , len 3 )
abc
** Grp 1 - ( pos 0 , len 3 )
abc
------------
** Grp 0 - ( pos 3 , len 3 )
abc
** Grp 1 - ( pos 3 , len 3 )
abc
结论:
即使您知道 Nth ,也可以从上一个前瞻中找到 Nth 在没有当前前瞻条件的情况下无法匹配。
抱歉,祝你好运!