【发布时间】:2015-10-08 18:28:27
【问题描述】:
请注意,这个问题是在 Julia 的上下文中,因此(据我所知)PCRE。
假设你有一个这样的字符串:
"sssppaaasspaapppssss"
并且您想单独匹配字符串末尾的重复字符(在我们的字符串的情况下,四个“s”字符 - 也就是说, matchall 给出 ["s","s" ,"s","s"],而不是 ["ssss"])。这很简单:
r"(.)(?=\1*$)"
它实际上是微不足道的(并且易于使用 - replace(r"(.)(?=\1*$)","hell","k") 将提供 "hekk" 而replace(r"(.)(?=\1*$)","hello","k") 将提供 "hellk")。并且可以通过将点换成更复杂的东西来推广重复模式:
r"(\S+)(?=( \1)*$)"
例如,它将独立匹配"abc abc defg abc h abc abc abc" 中“abc”的最后三个实例。
这就引出了一个问题……你将如何匹配字符串开始处的重复字符或模式?具体来说,以上面使用的方式使用正则表达式。
显而易见的方法是将上述正则表达式的方向反转为 r"(?<=^\1*)(.)" - 但 PCRE/Julia 不允许后向具有可变长度(除非它是固定变量,如 (?<=ab|cde)),因此引发错误。下一个想法是使用“\K”作为r"^\1*\K(.)" 的内容,但这只能匹配第一个字符(可能是因为它在匹配后“前进”,不再匹配插入符号)。
为了清楚起见:我正在寻找一个正则表达式,例如,导致
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+)(?=( \1)*$)","hello")
生产
"abc abc defg abc h hello hello hello"
【问题讨论】:
-
使用这个
^(\S+)(?:\s+\1)*,然后对空格字符进行分割, -
@AvinashRaj - 如果您通读完整的问题,您会发现我想知道它是否可以在没有多个步骤的情况下完成 - 也就是说,只需使用正则表达式。我可以使用字符串结尾等效项,
r"(.)(?=\1*$)"(或更一般的r"(\S+)(?=( \1)*$)")来做到这一点。 -
反转字符串。 ;-)
-
@KingMob - 如果您只想匹配一个方向,您可以这样做。但这不是正则表达式解决方案,如果您想在两个方向上匹配(例如,捕获字符串
"shorts shoes shop shovel shortstuff shoplifter shopshop"的每个部分中的第一个sho,而不是第二个shoshopshop,你需要从两个方向看 - 从某种意义上说,你基本上是在弄清楚哪个部分不是分隔符) -
好吧,您可以用
"hello$2"替换(\S+)((?= \1)|.*)(例如JavaScript),但不幸的是,您需要能够引用AFAIK 在Julia 中无法做到的替换字符串中的子匹配项:-(
标签: regex julia pcre regex-lookarounds lookbehind