【发布时间】:2010-09-04 16:20:47
【问题描述】:
我需要替换字符串中的非数字字符。
例如,“8-4545-225-144”需要为“84545225144”; “$334fdf890==-”必须是“334890”。
我该怎么做?
【问题讨论】:
我需要替换字符串中的非数字字符。
例如,“8-4545-225-144”需要为“84545225144”; “$334fdf890==-”必须是“334890”。
我该怎么做?
【问题讨论】:
''.join(c for c in S if c.isdigit())
【讨论】:
使用正则表达式是可能的。
import re
...
return re.sub(r'\D', '', theString)
【讨论】:
filter(str.isdigit, s) 比此处列出的任何其他内容都更快且 IMO 更清晰。
如果 s 是 unicode 类型,它也会抛出 TypeError。根据您想要的“数字”定义,这可能比替代 filter(type(s).isdigit, s) 或多或少有用,比我的 re 和理解版本稍慢但仍然更快。
编辑:虽然如果你是一个被 Python 3 困住的可怜虫,你将需要使用"".join(filter(str.isdigit, s)),这会让你陷入性能相当糟糕的境地。这样的进步。
【讨论】:
让我们为join 和re 版本计时:
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 是性能和可读性的赢家
【讨论】:
我更喜欢正则表达式,所以如果你喜欢,这里有一个方法
import re
myStr = '$334fdf890==-'
digts = re.sub('[^0-9]','',myStr)
这应该用 '' 替换所有出现的非数字,即什么都没有。所以 digts 变量应该是 '334890'
【讨论】:
虽然设置起来有点复杂,但根据我执行的时序测试,使用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
【讨论】: