【问题标题】:How can I remove the duplicated consecutive chars and reserve the first one using regex? [duplicate]如何删除重复的连续字符并使用正则表达式保留第一个字符? [复制]
【发布时间】:2017-01-14 14:03:00
【问题描述】:

我发现了一个代码 sn-p 删除重复的连续字符并通过网络上的正则表达式保留 Python 中的第一个字符,如下所示:

import re
re.sub(r'(?s)(.)(?=.*\1)','','aabbcc')  #'abc'

但是有一个缺陷,如果字符串是'aabbccaabb',它会忽略第一个'aa','bb'而变成'cab'。

re.sub(r'(?s)(.)(?=.*\1)','','aabbccaabb')  #'cab'

有没有办法通过正则表达式解决它?

【问题讨论】:

    标签: python regex string


    【解决方案1】:

    在没有正则表达式的情况下,检查前一个字符是否与当前字符相同,使用带有条件的列表推导并加入结果:

    s='aabbccaabb'
    print("".join([c for i,c in enumerate(s) if i==0 or s[i-1]!=c]))
    

    【讨论】:

    • Pretty Pythonic method.Thx.
    • 类似说明:z=list(s); t="".join([u for u,v in zip(z,['']+z)if u!=v])。这避免了循环中的双重测试,代价是将字符串转换为列表并创建第二个列表,尽管大部分工作都是以 C 速度完成的,所以它非常快。如果我们知道s 永远不会以 NUL 字符开头,我们可以避免使用t="".join([u for u,v in zip(s,'\0'+s)if u!=v]) 转换为列表,但我想这有点笨拙。 ;)
    • @PM2Ring 我总是忘记移动拉链的事情。谢谢。会记住这一点。
    • 还有s[0]+"".join([c for i,c in enumerate(s[1:]) if s[i]!=c])
    • @PM2Ring uvloop 不错 :)
    【解决方案2】:

    只需删除正面展望中的.*

    import re
    
    print re.sub(r'(?s)(.)(?=\1)','','aabbcc')
    print re.sub(r'(?s)(.)(?=\1)','','aabbccaabb')
    

    输出:

    abc
    abcab
    

    【讨论】:

    • 或:re.sub(r'(?s)(.)\1', r'\1', 'aabbccaabb')
    • @ScottCarpenter 它仅适用于 2 个重复字符。不会工作超过 2 个。
    • 还有一个小问题。如果我的字符串中有'\\',例如s = 'aa\\\\aa\\',我该如何实现,或者我需要考虑一个特殊的场合?
    • @ScottCarpenter re.sub(r'(.)\1+', r'\1', 'aaabbccaabb') 这行得通。
    • @Harrison 应该将重复的反斜杠替换为 1 还是不替换?
    猜你喜欢
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    相关资源
    最近更新 更多