파이썬을 사용하여 영숫자가 아닌 모든 문자를 문자열에서 제거하는 가장 좋은 방법은 무엇입니까?
이 질문 의 PHP 변형에 제시된 솔루션은 약간의 조정으로 작동하지만 아마도 나에게 '피 토닉'하지는 않습니다.
기록을 위해 마침표와 쉼표 (및 기타 문장 부호)를 제거하고 따옴표, 대괄호 등을 제거하고 싶지 않습니다.
파이썬을 사용하여 영숫자가 아닌 모든 문자를 문자열에서 제거하는 가장 좋은 방법은 무엇입니까?
이 질문 의 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
valid_characters = string.ascii_letters + string.digits
다음에 join(ch for ch in string.printable if ch in valid_characters)
그것을 빨리보다 6 마이크로이었다 isalnum()
.. 옵션 여전히 훨씬 느린 비록 정규 표현식보다
pattern.sub('', string.printable)
대신 RE 객체가있을 때 re.sub를 호출하는 것은 바보입니다!-).
re.compile('[\W_]+', re.UNICODE)
유니 코드 안전을 위해 사용 하십시오.
구조에 대한 정규식 :
import re
re.sub(r'\W+', '', your_string)
파이썬 정의에
'\W
==[^a-zA-Z0-9_]
, 제외 모든numbers
,letters
및_
\W
밑줄도 유지합니다.
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
string.punctuation
대신 대신 사용 하는 것이 좋습니다''.join(c for c in map(chr, range(256)) if not c.isalnum())
str
객체에는 작동 하지만 객체에는 작동 하지 않습니다 unicode
.
.join()
입니까?
어때요?
def ExtractAlphanumeric(InputString):
from string import ascii_letters, digits
return "".join([ch for ch in InputString if ch in (ascii_letters + digits)])
이것은 목록 이해를 사용하여 문자 InputString
가 결합 ascii_letters
및 digits
문자열 에있는 경우 문자 목록을 생성합니다 . 그런 다음 목록을 문자열로 결합합니다.
여기에 다른 답변에서 나온 것처럼 문자열 내용을 제한하려는 문자 집합을 정의하는 매우 간단하고 유연한 방법을 제공합니다. 이 경우 알파벳 숫자 PLUS 대시와 밑줄을 허용합니다. PERMITTED_CHARS
사용 사례에 따라 내 문자를 추가하거나 제거하십시오 .
PERMITTED_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"
someString = "".join(c for c in someString if c in PERMITTED_CHARS)
string.digits + string.ascii_letters + '_-'
.
SPECIAL_CHARS = '_-'
다음 사용할 수 있습니다.string.digits + string.ascii_letters + SPECIAL_CHARS
임의의 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
.
내가 올바르게 이해한다면 가장 쉬운 방법은 정규 표현식을 사용하는 것입니다. 유연성이 많지만 다른 간단한 방법은 루프 추적에 사용하는 것입니다. 예제 코드는 단어의 발생 횟수를 세어 사전에 저장합니다.
s = """An... essay is, generally, a piece of writing that gives the author's own
argument — but the definition is vague,
overlapping with those of a paper, an article, a pamphlet, and a short story. Essays
have traditionally been
sub-classified as formal and informal. Formal essays are characterized by "serious
purpose, dignity, logical
organization, length," whereas the informal essay is characterized by "the personal
element (self-revelation,
individual tastes and experiences, confidential manner), humor, graceful style,
rambling structure, unconventionality
or novelty of theme," etc.[1]"""
d = {} # creating empty dic
words = s.split() # spliting string and stroing in list
for word in words:
new_word = ''
for c in word:
if c.isalnum(): # checking if indiviual chr is alphanumeric or not
new_word = new_word + c
print(new_word, end=' ')
# if new_word not in d:
# d[new_word] = 1
# else:
# d[new_word] = d[new_word] +1
print(d)
이 답변이 도움이된다면 이것을 평가 해주세요!