Python: удаление символов, кроме цифр из строки

Как я могу удалить все символы, кроме чисел из строки?

11 Solutions collect form web for “Python: удаление символов, кроме цифр из строки”

В Python 2. *, безусловно, самым быстрым подходом является метод .translate :

 >>> x='aaa12333bb445bb54b5b52' >>> import string >>> all=string.maketrans('','') >>> nodigs=all.translate(all, string.digits) >>> x.translate(all, nodigs) '1233344554552' >>> 

string.maketrans создает таблицу трансляции (строку длиной 256), которая в этом случае совпадает с ''.join(chr(x) for x in range(256)) (просто быстрее сделать ;-). .translate применяет таблицу переводов (которая здесь не имеет значения, поскольку all существу означает идентификатор) И удаляет символы, присутствующие во втором аргументе – ключевую часть.

.translate работает по-разному в строках Unicode (и строки в Python 3 – мне задают вопросы, которые интересуют майор-релиз Python!) – не совсем это просто, не совсем так быстро, хотя все еще вполне пригодно для использования.

Назад к 2. *, разница в производительности впечатляет …:

 $ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"' 'x.translate(all, nodig)' 1000000 loops, best of 3: 1.04 usec per loop $ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)' 100000 loops, best of 3: 7.9 usec per loop 

Ускорение вещей в 7-8 раз – это не арахис, поэтому метод translate хорошо стоит знать и использовать. Другой популярный подход, не относящийся к RE:

 $ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())' 100000 loops, best of 3: 11.5 usec per loop 

на 50% медленнее, чем RE, поэтому подход .translate превосходит его на порядок.

В Python 3 или для Unicode вам нужно передать .translate сопоставление (с ординалами, а не с символами напрямую, как ключи), который возвращает None для того, что вы хотите удалить. Вот удобный способ выразить это для удаления «всего, кроме» нескольких символов:

 import string class Del: def __init__(self, keep=string.digits): self.comp = dict((ord(c),c) for c in keep) def __getitem__(self, k): return self.comp.get(k) DD = Del() x='aaa12333bb445bb54b5b52' x.translate(DD) 

также испускает '1233344554552' . Однако, помещая это в xx.py, мы имеем …:

 $ python3.1 -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)' 100000 loops, best of 3: 8.43 usec per loop $ python3.1 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)' 10000 loops, best of 3: 24.3 usec per loop 

… который показывает, что преимущество производительности исчезает, для таких задач «удаления» и становится снижением производительности.

Используйте re.sub , например:

 >>> import re >>> re.sub("\D", "", "aas30dsa20") '3020' 

\D соответствует любому несимметричному символу, поэтому код выше, по существу, заменяет каждый символ без цифры для пустой строки.

Или вы можете использовать filter , например (в Python 2k):

 >>> filter(lambda x: x.isdigit(), "aas30dsa20") '3020' 

Поскольку в Python 3k filter возвращает итератор вместо list , вы можете использовать следующее:

 >>> ''.join(filter(lambda x: x.isdigit(), "aas30dsa20")) '3020' 
 s=''.join(i for i in s if i.isdigit()) 

Другой вариант генератора.

Вы можете использовать фильтр:

 filter(lambda x: x.isdigit(), "dasdasd2313dsa") 

На python3.0 вы должны присоединиться к этому (вроде бы уродливый :()

 ''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa")) 

в соответствии с ответом Байера:

 ''.join(i for i in s if i.isdigit()) 
 x.translate(None, string.digits) 

удалит все цифры из строки. Чтобы удалить буквы и сохранить цифры, сделайте следующее:

 x.translate(None, string.letters) 

Вы можете легко сделать это с помощью Regex

 >>> import re >>> re.sub("\D","","£70,000") 70000 

В комментариях упоминается, что он хочет сохранить десятичное место. Это можно сделать с помощью метода re.sub (в соответствии со вторым и лучшим ответом IMHO), явно перечисляя символы, чтобы сохранить, например,

 >>> re.sub("[^0123456789\.]","","poo123.4and5fish") '123.45' 

Быстрая версия для Python 3:

 # xx3.py from collections import defaultdict import string _NoneType = type(None) def keeper(keep): table = defaultdict(_NoneType) table.update({ord(c): c for c in keep}) return table digit_keeper = keeper(string.digits) 

Вот сравнение производительности и регулярное выражение:

 $ python3.3 -mtimeit -s'import xx3; x="aaa12333bb445bb54b5b52"' 'x.translate(xx3.digit_keeper)' 1000000 loops, best of 3: 1.02 usec per loop $ python3.3 -mtimeit -s'import re; r = re.compile(r"\D"); x="aaa12333bb445bb54b5b52"' 'r.sub("", x)' 100000 loops, best of 3: 3.43 usec per loop 

Так что для меня это немного больше, чем в 3 раза быстрее, чем у регулярного выражения. Это также быстрее, чем class Del выше, потому что defaultdict делает все свои поисковые запросы на C, а не (медленном) Python. Вот эта версия для моей же системы, для сравнения.

 $ python3.3 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)' 100000 loops, best of 3: 13.6 usec per loop 

Уродливый, но работает:

 >>> s 'aaa12333bb445bb54b5b52' >>> a = ''.join(filter(lambda x : x.isdigit(), s)) >>> a '1233344554552' >>> 

Используйте выражение генератора:

 >>> s = "foo200bar" >>> new_s = "".join(i for i in s if i in "0123456789") 
Python - лучший язык программирования в мире.