Замена нечисловых символов

Мне нужно заменить нечисловые символы из строки.

Например, "8-4545-225-144" должно быть "84545225144"; "$ 334fdf890 == -" должно быть "334890".

Как я могу это сделать?

Ответ 1

''.join(c for c in S if c.isdigit())

Ответ 2

Возможно с регулярным выражением.

import re

...

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

Ответ 3

filter(str.isdigit, s) быстрее и IMO понятнее, чем что-либо еще, перечисленное здесь.

Он также выдает TypeError, если s является типом unicode. В зависимости от того, какое определение "цифр" вы хотите, это может быть более или менее полезным, чем альтернативный filter(type(s).isdigit, s), немного медленнее, но все же быстрее, чем версии re и понимания для меня.

Изменить: Хотя, если вы плохой присоски, застрявший с Python 3, вам нужно будет использовать "".join(filter(str.isdigit, s)), который сильно помещает вас в область эквивалентной производительности. Такой прогресс.

Ответ 4

Пусть время 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

Версия join намного лучше, чем у re, но, к сожалению, на 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

Хотя немного сложнее настроить, используя метод строки translate() для удаления символов, как показано ниже, может в 4-6 раз быстрее, чем при использовании join() или re.sub() в соответствии с проведенными мной тестами времени - поэтому, если это что-то сделано много раз, вы можете захотеть использовать это вместо этого.

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

Ответ 6

Я предпочитаю регулярные выражения, поэтому здесь, если вам нравится

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

Это должно заменить все нечисловые вхождения на "нет". Поэтому переменная digts должна быть "334890"