如何替换仅在字符串开头重复 characters/words 的模式?

How to replace pattern of repeating characters/words only at the beginning of the string?

请注意,这个问题是在 Julia 的上下文中,因此(据我所知)是 PCRE。

假设您有这样一个字符串:

"sssppaaasspaapppssss"

并且您想单独匹配字符串末尾的重复字符(在我们的字符串的情况下,四个 "s" 字符 - 也就是说,matchall 给出 ["s"、"s"、"s"、"s"],而不是 ["ssss"])。这很简单:

r"(.)(?=*$)"

这实际上是微不足道的(而且很容易使用 - replace(r"(.)(?=*$)","hell","k") 将给出 "hekk"replace(r"(.)(?=*$)","hello","k") 将给出 "hellk")。并且可以通过将点换成更复杂的东西来推广重复模式:

r"(\S+)(?=( )*$)"
例如,

将独立匹配 "abc abc defg abc h abc abc abc" 中 "abc" 的最后三个实例。

这会引出问题...您将如何匹配字符串 start 处的重复字符或模式?具体来说,按照上面的方式使用正则表达式。

显而易见的方法是将上述正则表达式的方向反转为 r"(?<=^*)(.)" - 但 PCRE/Julia 不允许 lookbehinds 具有可变长度(除非它是固定变量,例如 (?<=ab|cde)), 从而抛出错误。下一个想法是使用“\K”作为 r"^*\K(.)" 行的东西,但这只能匹配第一个字符(大概是因为它 "advances" 在匹配它之后,不再匹配插入符).

为清楚起见:我正在寻找一个正则表达式,例如,它会导致

replace("abc abc defg abc h abc abc abc",<regex here>,"hello")

生产

"hello hello defg abc h abc abc abc"

如您所见,它从一开始就将每个 "abc" 替换为 "hello",但直到第一个不匹配为止。我上面提供的反向在字符串的另一端执行此操作:

replace("abc abc defg abc h abc abc abc",r"(\S+)(?=( )*$)","hello")

产生

"abc abc defg abc h hello hello hello"

您可以使用匹配上一个匹配项之后或字符串开头位置的 \G 锚点。通过这种方式,您可以确保从字符串开头到最后一次出现的结果的连续性:

\G(\S+)( (?= ))?

demo

或者能够匹配到字符串的末尾:

\G(\S+)( (?=(?: |\z)))?

对于 PCRE 风格的引擎,不幸的是没有
就没有办法做到这一点 可变长度后视。

纯粹的解决方案是不可能的。
没有 \G 锚点技巧可以做到这一点。

这就是 \G 锚点不起作用的原因。

有了主播,你唯一能保证的就是最后一场比赛
导致匹配前向重叠被检查为相等
到当前比赛。

因此,您只能从头开始全局匹配最多 N-1 个重复项。

证明如下:

正则表达式:

 # (?:\G([a-c]+)(?=))

 (?:
      \G 
      ( [a-c]+ )                    # (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 没有当前 lookahead 的条件就无法匹配。

抱歉,祝你好运!
如果您找到纯正则表达式解决方案,请告诉我。