匹配并删除重复字符:替换多个 (3+) 非连续出现

M--*_*M-- 8 python regex string replace r

我正在寻找一种regex模式来匹配每个字符的第三个、第四个……出现。请看下面的说明:

例如,我有以下字符串:

111aabbccxccybbzaa1
Run Code Online (Sandbox Code Playgroud)

我想在第二次出现后替换所有重复的字符。输出将是:

11-aabbccx--y--z---
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试过的一些正则表达式模式:

使用以下正则表达式,我可以找到每个字符的最后一次出现:

(.)(?=.*\1)

或者使用这个我可以为连续的重复做它,但不能为任何重复做:

([a-zA-Z1-9])\1{2,}

Ice*_*can 9

非正则表达式 R 解决方案。拆分字符串。将此向量的 rowid >= 3 * 元素替换为'-'。将其粘贴回一起。

x <- '111aabbccxccybbzaa1'

xsplit <- strsplit(x, '')[[1]]
xsplit[data.table::rowid(xsplit) >= 3] <- '-'
paste(xsplit, collapse = '')

# [1] "11-aabbccx--y--z---"
Run Code Online (Sandbox Code Playgroud)

*rowid(x)是一个整数向量,每个元素表示来自相应元素的值x已被实现的次数。因此,如果xis的最后一个元素1,并且第四次1出现在 中x,则rowid(x)is的最后一个元素4


ctw*_*els 5

无需正则表达式即可轻松完成此操作:

请参阅此处使用的代码

s = '111aabbccxccybbzaa1'

for u in set(s):
    for i in [i for i in range(len(s)) if s[i]==u][2:]:
        s = s[:i]+'-'+s[i+1:]

print(s)
Run Code Online (Sandbox Code Playgroud)

结果:

11-aabbccx--y--z---
Run Code Online (Sandbox Code Playgroud)

这是如何运作的:

  1. for u in set(s)获取字符串中唯一字符的列表:{'c','a','b','y','1','z','x'}
  2. for i in ...循环我们在 3 中收集的索引。
  3. [i for i in range(len(s)) if s[i]==u][2:]循环遍历字符串中的每个字符并检查它是否匹配u(从步骤 1 开始),然后将数组从第二个元素切片到末尾(如果存在则删除前两个元素)
  4. 将字符串设置为s[:i]+'-'+s[i+1:]- 将索引之前的子字符串与-索引之后的子字符串连接起来,从而有效地省略原始字符。