Programing

파이썬에서 문자열에서 영숫자를 제외한 모든 것을 제거

lottogame 2020. 3. 18. 08:02
반응형

파이썬에서 문자열에서 영숫자를 제외한 모든 것을 제거


파이썬을 사용하여 영숫자가 아닌 모든 문자를 문자열에서 제거하는 가장 좋은 방법은 무엇입니까?

이 질문PHP 변형에 제시된 솔루션은 약간의 조정으로 작동하지만 아마도 나에게 '파이썬'인 것처럼 보이지는 않습니다.

기록을 위해 마침표와 쉼표 (및 기타 문장 부호)를 제거하고 따옴표, 대괄호 등을 제거하고 싶지 않습니다.


방금 호기심에서 일부 기능을 시간을 보냈습니다. 이 테스트에서는 문자열 string.printable(내장 string모듈의 일부) 에서 영숫자가 아닌 문자를 제거 합니다. 컴파일의 사용 '[\W_]+'pattern.sub('', str)빠른 것으로 밝혀졌다.

$ python -m timeit -s \
     "import string" \
     "''.join(ch for ch in string.printable if ch.isalnum())" 
10000 loops, best of 3: 57.6 usec per loop

$ python -m timeit -s \
    "import string" \
    "filter(str.isalnum, string.printable)"                 
10000 loops, best of 3: 37.9 usec per loop

$ python -m timeit -s \
    "import re, string" \
    "re.sub('[\W_]', '', string.printable)"
10000 loops, best of 3: 27.5 usec per loop

$ python -m timeit -s \
    "import re, string" \
    "re.sub('[\W_]+', '', string.printable)"                
100000 loops, best of 3: 15 usec per loop

$ python -m timeit -s \
    "import re, string; pattern = re.compile('[\W_]+')" \
    "pattern.sub('', string.printable)" 
100000 loops, best of 3: 11.2 usec per loop

구조에 대한 정규식 :

import re
re.sub(r'\W+', '', your_string)

파이썬 정의에 '\W== [^a-zA-Z0-9_], 제외 모든 numbers, letters_


str.translate () 메소드를 사용하십시오 .

당신이 이것을 자주 할 것이라고 가정 :

(1) 한 번 삭제하려는 모든 문자가 포함 된 문자열을 만듭니다.

delchars = ''.join(c for c in map(chr, range(256)) if not c.isalnum())

(2) 줄을 긁을 때마다 :

scrunched = s.translate(None, delchars)

설치 비용은 아마도 re.compile과 유리하게 비교 될 것입니다. 한계 비용은 훨씬 낮습니다.

C:\junk>\python26\python -mtimeit -s"import string;d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s=string.printable" "s.translate(None,d)"
100000 loops, best of 3: 2.04 usec per loop

C:\junk>\python26\python -mtimeit -s"import re,string;s=string.printable;r=re.compile(r'[\W_]+')" "r.sub('',s)"
100000 loops, best of 3: 7.34 usec per loop

참고 : 벤치 마크 데이터로 string.printable을 사용하면 패턴 '[\ W _] +'에 불공정 한 이점이 있습니다 . 영숫자가 아닌 문자는 모두 한 묶음에 있습니다. 일반적인 데이터에는 둘 이상의 대체 문자가 있습니다.

C:\junk>\python26\python -c "import string; s = string.printable; print len(s),repr(s)"
100 '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

re.sub에게 더 많은 작업을 수행하면 어떻게됩니까?

C:\junk>\python26\python -mtimeit -s"d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s='foo-'*25" "s.translate(None,d)"
1000000 loops, best of 3: 1.97 usec per loop

C:\junk>\python26\python -mtimeit -s"import re;s='foo-'*25;r=re.compile(r'[\W_]+')" "r.sub('',s)"
10000 loops, best of 3: 26.4 usec per loop

시도해 볼 수 있습니다 :

print ''.join(ch for ch in some_string if ch.isalnum())

>>> import re
>>> string = "Kl13@£$%[};'\""
>>> pattern = re.compile('\W')
>>> string = re.sub(pattern, '', string)
>>> print string
Kl13

어때요?

def ExtractAlphanumeric(InputString):
    from string import ascii_letters, digits
    return "".join([ch for ch in InputString if ch in (ascii_letters + digits)])

이것은 목록 이해를 사용하여 문자 InputString가 결합 ascii_lettersdigits문자열 에있는 경우 문자 목록을 생성합니다 . 그런 다음 목록을 문자열로 결합합니다.


여기에 다른 답변에서 나온 것처럼 문자열 내용을 제한하려는 문자 집합을 정의하는 매우 간단하고 유연한 방법을 제공합니다. 이 경우 알파벳 숫자 PLUS 대시와 밑줄을 허용합니다. PERMITTED_CHARS사용 사례에 따라 내 문자를 추가하거나 제거하십시오 .

PERMITTED_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-" 
someString = "".join(c for c in someString if c in PERMITTED_CHARS)

for char in my_string:
    if not char.isalnum():
        my_string = my_string.replace(char,"")

sent = "".join(e for e in sent if e.isalpha())

임의의 ASCII 인쇄 가능 문자열을 사용한 타이밍 :

from inspect import getsource
from random import sample
import re
from string import printable
from timeit import timeit

pattern_single = re.compile(r'[\W]')
pattern_repeat = re.compile(r'[\W]+')
translation_tb = str.maketrans('', '', ''.join(c for c in map(chr, range(256)) if not c.isalnum()))


def generate_test_string(length):
    return ''.join(sample(printable, length))


def main():
    for i in range(0, 60, 10):
        for test in [
            lambda: ''.join(c for c in generate_test_string(i) if c.isalnum()),
            lambda: ''.join(filter(str.isalnum, generate_test_string(i))),
            lambda: re.sub(r'[\W]', '', generate_test_string(i)),
            lambda: re.sub(r'[\W]+', '', generate_test_string(i)),
            lambda: pattern_single.sub('', generate_test_string(i)),
            lambda: pattern_repeat.sub('', generate_test_string(i)),
            lambda: generate_test_string(i).translate(translation_tb),

        ]:
            print(timeit(test), i, getsource(test).lstrip('            lambda: ').rstrip(',\n'), sep='\t')


if __name__ == '__main__':
    main()

결과 (Python 3.7) :

       Time       Length                           Code                           
6.3716264850008880  00  ''.join(c for c in generate_test_string(i) if c.isalnum())
5.7285426190064750  00  ''.join(filter(str.isalnum, generate_test_string(i)))
8.1875841680011940  00  re.sub(r'[\W]', '', generate_test_string(i))
8.0002205439959650  00  re.sub(r'[\W]+', '', generate_test_string(i))
5.5290945199958510  00  pattern_single.sub('', generate_test_string(i))
5.4417179649972240  00  pattern_repeat.sub('', generate_test_string(i))
4.6772285089973590  00  generate_test_string(i).translate(translation_tb)
23.574712151996210  10  ''.join(c for c in generate_test_string(i) if c.isalnum())
22.829975890002970  10  ''.join(filter(str.isalnum, generate_test_string(i)))
27.210196289997840  10  re.sub(r'[\W]', '', generate_test_string(i))
27.203713296003116  10  re.sub(r'[\W]+', '', generate_test_string(i))
24.008979928999906  10  pattern_single.sub('', generate_test_string(i))
23.945240008994006  10  pattern_repeat.sub('', generate_test_string(i))
21.830899796994345  10  generate_test_string(i).translate(translation_tb)
38.731336012999236  20  ''.join(c for c in generate_test_string(i) if c.isalnum())
37.942474347000825  20  ''.join(filter(str.isalnum, generate_test_string(i)))
42.169366310001350  20  re.sub(r'[\W]', '', generate_test_string(i))
41.933375883003464  20  re.sub(r'[\W]+', '', generate_test_string(i))
38.899814646996674  20  pattern_single.sub('', generate_test_string(i))
38.636144253003295  20  pattern_repeat.sub('', generate_test_string(i))
36.201238164998360  20  generate_test_string(i).translate(translation_tb)
49.377356811004574  30  ''.join(c for c in generate_test_string(i) if c.isalnum())
48.408927293996385  30  ''.join(filter(str.isalnum, generate_test_string(i)))
53.901889764994850  30  re.sub(r'[\W]', '', generate_test_string(i))
52.130339455994545  30  re.sub(r'[\W]+', '', generate_test_string(i))
50.061149017004940  30  pattern_single.sub('', generate_test_string(i))
49.366573111998150  30  pattern_repeat.sub('', generate_test_string(i))
46.649754120997386  30  generate_test_string(i).translate(translation_tb)
63.107938601999194  40  ''.join(c for c in generate_test_string(i) if c.isalnum())
65.116287978999030  40  ''.join(filter(str.isalnum, generate_test_string(i)))
71.477421126997800  40  re.sub(r'[\W]', '', generate_test_string(i))
66.027950693998720  40  re.sub(r'[\W]+', '', generate_test_string(i))
63.315361931003280  40  pattern_single.sub('', generate_test_string(i))
62.342320287003530  40  pattern_repeat.sub('', generate_test_string(i))
58.249303059004890  40  generate_test_string(i).translate(translation_tb)
73.810345625002810  50  ''.join(c for c in generate_test_string(i) if c.isalnum())
72.593953348005020  50  ''.join(filter(str.isalnum, generate_test_string(i)))
76.048324580995540  50  re.sub(r'[\W]', '', generate_test_string(i))
75.106637657001560  50  re.sub(r'[\W]+', '', generate_test_string(i))
74.681338128997600  50  pattern_single.sub('', generate_test_string(i))
72.430461594005460  50  pattern_repeat.sub('', generate_test_string(i))
69.394243567003290  50  generate_test_string(i).translate(translation_tb)

str.maketrans& str.translate가 가장 빠르지 만 ASCII가 아닌 모든 문자를 포함합니다. re.compile& pattern.sub는 느리지 만 ''.join& 보다 빠릅니다 filter.

참고 URL : https://stackoverflow.com/questions/1276764/stripping-everything-but-alphanumeric-chars-from-a-string-in-python

반응형