Pythonで文字列からすべての非数値文字を削除するにはどうすればよいですか?
>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'
これが最も効率的な方法かどうかはわかりませんが、次のとおりです。
>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'
''.join
部分は、結果のすべての文字を、間に文字を入れずに結合することを意味します。それから残りはリストの内包です。ここでは(おそらく推測できるように)条件isdigit
に一致する文字列の部分のみを取得します。
これは文字列とUnicodeオブジェクトに対して機能するはずです:
# python <3.0
def only_numerics(seq):
return filter(type(seq).isdigit, seq)
# python ≥3.0
def only_numerics(seq):
seq_type= type(seq)
return seq_type().join(filter(seq_type.isdigit, seq))
別のオプションをミックスに追加するために、string
モジュール内にいくつかの便利な定数があります。他のケースではより便利ですが、ここで使用できます。
>>> from string import digits
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
モジュールには、次のようないくつかの定数があります。
ascii_letters
(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)hexdigits
(0123456789abcdefABCDEF)これらの定数を頻繁に使用している場合は、frozenset
に変換する価値があります。これにより、O(n)ではなくO(1)ルックアップが有効になります。nは元の文字列の定数の長さです。
>>> digits = frozenset(digits)
>>> ''.join(c for c in "abc123def456" if c in digits)
'123456'
このような削除操作を1つまたは2つ以上(または1つだけでも非常に長い文字列で!)実行する必要がある場合、最速のアプローチは、文字列のtranslate
メソッドに依存することです準備が必要です:
>>> import string
>>> allchars = ''.join(chr(i) for i in xrange(256))
>>> identity = string.maketrans('', '')
>>> nondigits = allchars.translate(identity, string.digits)
>>> s = 'abc123def456'
>>> s.translate(identity, nondigits)
'123456'
translate
メソッドは異なりますが、バイト文字列よりもUnicode文字列で使用する方が簡単です。
>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
...
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'
特に、Unicode文字列に非常に高いord値を持つ文字が含まれる可能性がある場合は、実際の辞書ではなくマッピングクラスを使用することをお勧めします(辞書が非常に大きくなります;-)。例えば:
>>> class keeponly(object):
... def __init__(self, keep):
... self.keep = set(ord(c) for c in keep)
... def __getitem__(self, key):
... if key in self.keep:
... return key
... return None
...
>>> s.translate(keeponly(string.digits))
u'123456'
>>>
@Ned Batchelderと@newacctは正しい答えを提供しましたが、...
文字列にカンマ(、)十進数(。)がある場合に備えて:
import re
re.sub("[^\d\.]", "", "$1,999,888.77")
'1999888.77'