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

Gle*_*n O 8 regex pcre lookbehind julia regex-lookarounds

请注意,这个问题是在Julia的背景下,因此(据我所知)是PCRE.

假设你有一个像这样的字符串:

"sssppaaasspaapppssss"
Run Code Online (Sandbox Code Playgroud)

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

r"(.)(?=\1*$)"
Run Code Online (Sandbox Code Playgroud)

它实际上是微不足道的(并且很容易使用 - replace(r"(.)(?=\1*$)","hell","k")会给予"hekk"同时replace(r"(.)(?=\1*$)","hello","k")给予"hellk").并且可以通过将点切换为更复杂的点来重复模式:

r"(\S+)(?=( \1)*$)"
Run Code Online (Sandbox Code Playgroud)

例如,它将独立匹配"abc"的最后三个实例"abc abc defg abc h abc abc abc".

然后导致问题...如何匹配字符串开头的重复字符或模式,而不是?具体来说,以上面使用的方式使用正则表达式.

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

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

replace("abc abc defg abc h abc abc abc",<regex here>,"hello")
Run Code Online (Sandbox Code Playgroud)

生产

"hello hello defg abc h abc abc abc"
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,它从一开始用"你好"替换每个"abc",但直到第一次不匹配.我在上面提供的反向链接在字符串的另一端执行此操作:

replace("abc abc defg abc h abc abc abc",r"(\S+)(?=( \1)*$)","hello")
Run Code Online (Sandbox Code Playgroud)

产生

"abc abc defg abc h hello hello hello"
Run Code Online (Sandbox Code Playgroud)

Cas*_*yte 8

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

\G(\S+)( (?=\1 ))?
Run Code Online (Sandbox Code Playgroud)

演示

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

\G(\S+)( (?=\1(?: |\z)))?
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这是整场比赛,而不是比赛对象.而且我知道有一些解决方法.正如我所说,我真正希望的是一种方法,可以在字符串的末尾完成同样的事情 - 很容易匹配字符串末尾的重复模式......但是在开始时,我见过的最好的是你的技巧,如果模式没有很好的分隔符,它就不起作用.如果没人提供能够在接下来几天内完美完成的解决方案,那么我现在会尽可能地接受您的回答. (2认同)