파이썬에서 문자열에서 숫자가 아닌 문자를 모두 제거


답변:


267
>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'

90
re.sub (r "\ D", "", "sdkjh987978asd098as0980a98sd")
newacct

3
다시 가져올 수 있습니다
James Koss

90

이것이 가장 효율적인 방법인지 확실하지 않지만

>>> ''.join(c for c in "abc123def456" if c.isdigit())
'123456'

''.join부분은 모든 결과 문자를 사이에 문자없이 결합하는 것을 의미합니다. 그런 다음 나머지는 목록 이해입니다. 어쩌면 짐작할 수 있듯이 조건과 일치하는 문자열 부분 만 취합니다 isdigit.


1
그것은 반대입니다. "c.isdigit ()"이 아니라고 생각합니다.
Ryan R. Rosario

7
숫자가 아닌 모든 ==를 제거하고 숫자 만 유지하십시오.
Mark Rushakoff

10
나는이 간단한 기능을 위해이 접근법이 다시 끌어 올 필요가 없다는 것을 좋아합니다.
triunenature

str.translate를 사용한 구현과 달리이 솔루션은 Python 2.7 및 3.4에서 모두 작동합니다. 감사합니다!
Alex

1
나는이 대안을 선호한다. 정규식을 사용하면 나에게 과도한 것처럼 보입니다.
alfredocambera

18

이것은 Python2의 문자열과 유니 코드 객체와 Python3의 문자열과 바이트 모두에서 작동합니다.

# 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))

9

믹스에 다른 옵션을 추가하기 위해 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'

''.join (c.isdigit () 인 경우 "abc123def456"에서 c의 c는 python 3.4에서 작동 함)
Eino Mäkitalo

7

@ Ned Batchelder와 @newacct가 정답을 제공했지만 ...

문자열에 쉼표 (,) decimal (.)이있는 경우를 대비하여 :

import re
re.sub("[^\d\.]", "", "$1,999,888.77")
'1999888.77'

5

하나 또는 두 개 이상의 제거 작업을 수행 해야하는 경우 (또는 심지어 하나의 문자열이지만 매우 긴 문자열에서!) 가장 빠른 방법은 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방법은 바이트 문자열, btw보다 유니 코드 문자열에서 다르며 어쩌면 사용하기가 더 간단합니다.

>>> unondig = dict.fromkeys(xrange(65536))
>>> for x in string.digits: del unondig[ord(x)]
... 
>>> s = u'abc123def456'
>>> s.translate(unondig)
u'123456'

실제 dict 대신 매핑 클래스를 사용하려고 할 수 있습니다. 특히 유니 코드 문자열에 ord 값이 매우 높은 문자가 포함될 수있는 경우 (dict가 지나치게 큰 ;-) 예를 들면 다음과 같습니다.

>>> 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'
>>> 

2
(1) 매직 넘버를 하드 코딩하지 마십시오. s / 65536 / sys.maxunicode / (2) 입력은 "잠재적으로"입력에 (sys.maxunicode - number_of_non_numeric_chars)항목이 포함되어 있기 때문에 무조건 "과도하게 너무 큰"것 입니다. (3) string.digits가 충분하지 않은지 고려하여 유니 코드 데이터 모듈을 열어야 할 필요가 있습니다 .4) 단순성과 잠재력을 위해 re.sub (r '(? u) \ D +', u '', text)를 고려하십시오. 속도.
John Machin

2

많은 정답이지만 정규 표현식을 사용하지 않고 직접 부동 소수점으로 원할 경우 :

x= '$123.45M'

float(''.join(c for c in x if (c.isdigit() or c =='.'))

123.45

필요에 따라 쉼표의 포인트를 변경할 수 있습니다.

숫자가 정수라는 것을 알고 있다면 이것을 변경하십시오.

x='$1123'    
int(''.join(c for c in x if c.isdigit())

1123

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.