我正在寻找一种regex
模式,该模式将与每个字符的第三,第四,...匹配。请在下面进行澄清:
例如,我有以下字符串:
111aabbccxccybbzaa1
我想在第二次出现后替换所有重复的字符。输出将是:
11-aabbccx--y--z---
到目前为止我尝试过的一些正则表达式模式:
使用以下正则表达式,我可以找到每个字符的最后一次出现:(.)(?=.*\1)
或者使用此方法,我可以将其用于连续重复,但不能重复:([a-zA-Z1-9])\1{2,}
答案 0 :(得分:6)
非正则表达式R解决方案。分割字串。用'-'
替换该rowid> = 3 *的向量的元素。粘贴回去。
x <- '111aabbccxccybbzaa1'
xsplit <- strsplit(x, '')[[1]]
xsplit[data.table::rowid(xsplit) >= 3] <- '-'
paste(xsplit, collapse = '')
# [1] "11-aabbccx--y--z---"
* rowid(x)
是一个整数向量,每个元素表示实现x
的相应元素的值的次数。因此,如果x
的最后一个元素是1
,并且这是1
中第四次出现x
,那么rowid(x)
的最后一个元素就是{{1 }}。
答案 1 :(得分:3)
您无需使用正则表达式即可轻松完成此操作:
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)
结果:
11-aabbccx--y--z---
这是如何工作的:
for u in set(s)
获取字符串中的唯一字符列表:{'c','a','b','y','1','z','x'}
for i in ...
遍历我们在3中收集的索引。[i for i in range(len(s)) if s[i]==u][2:]
遍历字符串中的每个字符,并检查它是否与u
匹配(从步骤1开始),然后将数组从第二个元素切到结尾(删除前两个元素)如果存在)s[:i]+'-'+s[i+1:]
-用-
将子字符串连接到索引,然后将索引后面的子字符串连接起来,从而有效地省略了原始字符。答案 2 :(得分:3)
带有gsubfn
library(gsubfn)
p <- proto(fun = function(this, x) if (count >=3) '-' else x)
for(i in c(0:9, letters)) x <- gsubfn(i, p, x)
x
#[1] "11-aabbccx--y--z---"
x <- '111aabbccxccybbzaa1'
答案 3 :(得分:1)
使用pandas
的另一种方法。
import pandas as pd
s = '111aabbccxccybbzaa1'
# 11-aabbccx--y--z---
df = pd.DataFrame({'Data': list(s)})
df['Count'] = 1
df['cumsum'] = df[['Data', 'Count']].groupby('Data').cumsum()
df.loc[df['cumsum']>=3, 'Data'] = '-'
''.join(df.Data.to_list())
输出:
11-aabbccx--y--z---
答案 4 :(得分:1)
没有正则表达式python单行代码:
s = "111aabbccxccybbzaa1"
print("".join(char if s.count(char, 0, i) < 2 else "-" for i, char in enumerate(s)))
# ==> "11-aabbccx--y--z---"
这将枚举整个字符串,计算当前字符在其后的出现次数,并且仅在该字符是前2个字符之一(否则为破折号)时才将其放置。
答案 5 :(得分:0)
感谢 WiktorStribiżew, Stefan Pochmann 和气泡泡泡。为了完整起见,我将发布评论中讨论的可能的regex
解决方案;
这仅可用于支持无限宽后向查找的正则表达式。使用Python PyPi regex模块,我们可以执行以下操作:
#python 2.7.12
import regex
s = "111aabbccxccybbzaa1"
print(regex.sub(r'(.)(?<=^(?:(?:(?!\1).)*\1){2,}(?:(?!\1).)*\1)', '-', s)) #Wiktor Stribizew
## 11-aabbccx--y--z---
print(regex.sub(r'(.)(?<=(.*\1){3})', '-', s)) #Stefan Pochmann
## 11-aabbccx--y--z---
print(regex.sub(r'(.)(?<=(?:.*\1){3})', '-', s)) #Wiktor Stribizew
## 11-aabbccx--y--z---
print(regex.sub(r'(.)(?<=(?:\1.*?){2}\1)', '-', s)) #bobble bubble
## 11-aabbccx--y--z---