문자열에서 숫자를 제외한 모든 문자를 제거하려면 어떻게합니까?
문자열에서 숫자를 제외한 모든 문자를 제거하려면 어떻게합니까?
답변:
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
본질적으로 ID를 의미 하므로 관련이 없음 ). 두 번째 인수 인 핵심 부분에있는 문자를 삭제합니다.
.translate
매우 다르게 유니 코드 문자열에서 작동 (파이썬 3 문자열 - 내가 할 소원 질문 파이썬의 주요 릴리스가 관심 인 지정!) - 확실히이 간단한, 꽤 이렇게 빨리,하지만 아직도 확실히 가능.
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
RE보다 50 % 느리므로 .translate
접근 방식이이를 훨씬 능가합니다.
Python 3 또는 유니 코드의 경우 삭제하려는 항목을 .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
... 이러한 "삭제"작업에 대한 성능 이점이 사라지고 성능이 저하됨을 나타냅니다.
x.translate(None, string.digits)
실제로 결과 'aaabbbbbb'
는 의도 한 것과 반대입니다.
all
내장을 재정의하는 중 ... 확실하지 않습니다!
다음 re.sub
과 같이 사용하십시오 .
>>> import re
>>> re.sub('\D', '', 'aas30dsa20')
'3020'
\D
숫자가 아닌 문자와 일치하므로 위의 코드는 기본적으로 빈 문자열의 숫자가 아닌 모든 문자를 대체합니다.
또는 filter
(Python 2에서) 다음과 같이 사용할 수 있습니다 .
>>> filter(str.isdigit, 'aas30dsa20')
'3020'
Python 3에서는 filter
a 대신 반복자를 반환하므로 대신 list
다음을 사용할 수 있습니다.
>>> ''.join(filter(str.isdigit, 'aas30dsa20'))
'3020'
isdigit
. 발전기 isdigt
가 그들 사이에 중간입니다
r
원시 문자열 :re.sub(r"\D+", "", "aas30dsa20")
s=''.join(i for i in s if i.isdigit())
다른 발전기 변형.
필터를 사용할 수 있습니다 :
filter(lambda x: x.isdigit(), "dasdasd2313dsa")
python3.0에서는 이것을 결합해야합니다 (kinda ugly :()
''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))
str
할 수 list
있는지가 py2와 py3 모두 작동하는지 :''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
x.translate(None, string.digits)
문자열에서 모든 숫자를 삭제합니다. 문자를 삭제하고 숫자를 유지하려면 다음과 같이하십시오.
x.translate(None, string.letters)
TypeError
: translate ()는 정확히 하나의 인수 (2 주어진)를 취합니다. 이 질문이 현재 상태에서 찬성되는 이유는 상당히 실망 스럽습니다.
op는 소수점 이하 자릿수를 유지하고 싶다는 의견을 언급합니다. 이것은 유지하기 위해 문자를 명시 적으로 나열하여 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 배 이상 빠릅니다. 파이썬보다 (느린) C가 아닌 C에서 모든 조회를 수행 class Del
하기 때문에 위 보다 빠릅니다 defaultdict
. 비교를 위해 동일한 시스템에 해당 버전이 있습니다.
$ 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'
>>>
list(s)
?
filter(lambda x: x.isdigit(), s)
나를 위해 잘 작동했습니다. ... 오, 파이썬 2.7을 사용하고 있기 때문입니다.
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
루프 당 100000 개의 루프 (3 : 2.48 usec 이상)
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
100000 루프, 최고 3 : 2.02 루프 당 루프
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
루프 당 100000 개의 루프 (3 : 2.37 usec 이상)
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
루프 당 100000 개의 루프, 최고 3 : 1.97 usec
조인이 하위보다 빠릅니다.