【问题标题】:Replace non-numeric characters [duplicate]替换非数字字符[重复]
【发布时间】:2010-09-04 16:20:47
【问题描述】:

我需要替换字符串中的非数字字符。

例如,“8-4545-225-144”需要为“84545225144”; “$334fdf890==-”必须是“334890”。

我该怎么做?

【问题讨论】:

    标签: python regex string


    【解决方案1】:
    ''.join(c for c in S if c.isdigit())
    

    【讨论】:

    • 我讨厌人们猛烈抨击列表理解,而生成器表达式是正确的选择。先生,您赢得了一次互联网(和一次投票)。
    • +1 用于非正则表达式解决方案。我讨厌人们对所有事情都使用正则表达式,有些目标更适合非正则表达式解决方案
    • @killown:我个人认为 regex 选项更具可读性。也许是因为我在正则表达式方面做了很多工作,但是查看@KennyTM 的代码我可以立即看到它的作用;这需要我一秒钟才能理解。
    【解决方案2】:

    使用正则表达式是可能的。

    import re
    
    ...
    
    return re.sub(r'\D', '', theString)
    

    【讨论】:

      【解决方案3】:

      filter(str.isdigit, s) 比此处列出的任何其他内容都更快且 IMO 更清晰。

      如果 s 是 unicode 类型,它也会抛出 TypeError。根据您想要的“数字”定义,这可能比替代 filter(type(s).isdigit, s) 或多或少有用,比我的 re 和理解版本稍慢但仍然更快。

      编辑:虽然如果你是一个被 Python 3 困住的可怜虫,你将需要使用"".join(filter(str.isdigit, s)),这会让你陷入性能相当糟糕的境地。这样的进步。

      【讨论】:

        【解决方案4】:

        让我们为joinre 版本计时:

        In [3]: import re
        
        In [4]: def withRe(theString): return re.sub('\D', '', theString)
           ...:
        
        In [5]:
        
        In [6]: def withJoin(S): return ''.join(c for c in S if c.isdigit())
           ...:
        
        
        In [11]: s = "8-4545-225-144"
        
        In [12]: %timeit withJoin(s)
        100000 loops, best of 3: 6.89 us per loop
        
        In [13]: %timeit withRe(s)
        100000 loops, best of 3: 4.77 us per loop
        

        re 相比,join 版本要好得多,但不幸的是慢了 50%。因此,如果性能是一个问题,则可能需要牺牲优雅。

        编辑

        In [16]: def withFilter(s): return filter(str.isdigit, s)
           ....:
        In [19]: %timeit withFilter(s)
        100000 loops, best of 3: 2.75 us per loop
        

        看起来filter 是性能和可读性的赢家

        【讨论】:

          【解决方案5】:

          我更喜欢正则表达式,所以如果你喜欢,这里有一个方法

          import re
          myStr = '$334fdf890==-'
          digts = re.sub('[^0-9]','',myStr) 
          

          这应该用 '' 替换所有出现的非数字,即什么都没有。所以 digts 变量应该是 '334890'

          【讨论】:

            【解决方案6】:

            虽然设置起来有点复杂,但根据我执行的时序测试,使用translate() 字符串方法删除如下所示的字符可以比使用join()re.sub() 快4-6 倍-- 因此,如果它是多次执行的操作,您可能需要考虑使用它。

            nonnumerics = ''.join(c for c in ''.join(chr(i) for i in range(256)) if not c.isdigit())
            
            astring = '123-$ab #6789'
            print astring.translate(None, nonnumerics)
            # 1236789
            

            【讨论】:

            • str.translate 方法优于 string.translate。
            • @Roger Pate,好点,旧习惯很难改掉......我已经相应地更新了答案中的代码。感谢您指出并允许我改进示例代码。
            猜你喜欢
            • 1970-01-01
            • 2021-02-21
            • 2019-01-02
            • 1970-01-01
            • 1970-01-01
            • 2011-08-31
            • 2020-12-15
            • 2013-07-01
            • 1970-01-01
            相关资源
            最近更新 更多