从单词中删除重复的字符

11

我想知道将"haaaaapppppyyy"这样的内容转换成"haappyy"最好的方法是什么。

基本上,当解析俚语时,人们有时会重复字符以增加强调效果。

我想知道怎么做才是最好的呢?使用set()无法正常工作,因为字母的顺序显然很重要。

有任何想法吗?我正在使用Python + NLTK。


基本上,我只在同一个单词中有一个字母连续重复超过2次时才执行此操作,因此实际上该单词将会是“haappy”。不过,我可以使用 enchant 进行拼写检查。 - user179169
哦,抱歉,我忘记了我重复了“y”,是的,应该是“haappyy”。 - user179169
匹配字典也是一个有趣的问题:通过去掉重复字符找到最短的实际单词。这并不容易,因为有些单词有两个或更多的双字母(比如“bookkeeper”)。 - alexis
4个回答

33
可以使用正则表达式来实现:
>>> import re
>>> re.sub(r'(.)\1+', r'\1\1', "haaaaapppppyyy")     
'haappyy'

(.)\1+会将任何字符 (.) 后面跟着一个或多个相同的字符(因为反向引用 \1 必须是相同的)替换为两个字符。


6
我会使用 r'(.)\1{2,}' 代替,这样重复的字符就不会被替换掉了(现在你只是用它们替换它们自己)。这应该能让你更快一些。 - Tim Pietzcker
@TimPietzcker 这并没有真正加速替换。我的第一个想法与larsmans相同,即正则表达式应该比group/join快得多,但似乎并非如此。 - Howard
@Howard:如果字符串包含许多双字母,它就会。显然不是在这个测试字符串上。 - Tim Pietzcker

8
您可以使用 itertools.groupby 来压缩多个字母的出现:
>>> ''.join(c for c, _ in groupby("haaaaapppppyyy"))
'hapy'

同样地,你可以通过groupby得到haappyy

>>> ''.join(''.join(s)[:2] for _, s in groupby("haaaaapppppyyy"))
'haappyy'

1
您应该不使用 reduce 或正则表达式来完成它:
>>> s = 'hhaaaaapppppyyy'
>>> ''.join(['' if i>1 and e==s[i-2] else e for i,e in enumerate(s)])
'haappyy'

重复次数在上述代码中被硬编码为>1-2。一般情况如下:
>>> reps = 1
>>> ''.join(['' if i>reps-1 and e==s[i-reps] else e for i,e in enumerate(s)])
'hapy'

0

这是一种做法(受明显约束,即Python不会说英语)。

>>> s="haaaappppyy"
>>> reduce(lambda x,y: x+y if x[-2:]!=y*2 else x, s, "")
'haappyy'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接