Jaki jest najlepszy sposób na usunięcie wszystkich znaków alfanumerycznych z ciągu przy użyciu Pythona?
Rozwiązania przedstawione w wariancie PHP tego pytania prawdopodobnie będą działać z pewnymi drobnymi poprawkami, ale nie wydają mi się zbyt „pytoniczne”.
Dla przypomnienia, nie chcę tylko usuwać kropek i przecinków (i innych znaków interpunkcyjnych), ale także cytatów, nawiasów itp.
Odpowiedzi:
Właśnie przeliczyłem niektóre funkcje z ciekawości. W tych testach usuwam znaki niealfanumeryczne z łańcucha
string.printable
(część wbudowanegostring
modułu). Zastosowanie skompilowanego'[\W_]+'
ipattern.sub('', str)
okazało się najszybsze.źródło
valid_characters = string.ascii_letters + string.digits
następniejoin(ch for ch in string.printable if ch in valid_characters)
było to o 6 mikrosekund szybsze niżisalnum()
opcja. Wciąż jednak znacznie wolniejsze niż regexp.pattern.sub('', string.printable)
zamiast tego - głupio wywołać re.sub, gdy masz obiekt RE! -).re.compile('[\W_]+', re.UNICODE)
aby uczynić go bezpiecznym dla Unicode.Wyrażenia regularne na ratunek:
źródło
\W
zachowa również podkreślenia.Użyj str.translate () .
Zakładając, że będziesz to robił często:
(1) Raz utwórz ciąg zawierający wszystkie znaki, które chcesz usunąć:
(2) Ilekroć chcesz skrobać ciąg:
Koszt instalacji prawdopodobnie porównuje się korzystnie z re.compile; koszt krańcowy jest znacznie niższy:
Uwaga: użycie string.printable jako danych porównawczych daje wzorowi „[\ W _] +” nieuczciwą przewagę ; wszystkie znaki niealfanumeryczne znajdują się w jednej wiązce ... w typowych danych do wykonania byłoby więcej niż jedno podstawienie:
Oto, co się stanie, jeśli dasz re.sub nieco więcej pracy:
źródło
string.punctuation
Zamiast''.join(c for c in map(chr, range(256)) if not c.isalnum())
str
obiektów, ale nie dlaunicode
obiektów..join()
?Możesz spróbować:
źródło
źródło
Co powiesz na:
Działa to poprzez użycie rozumienia listy w celu utworzenia listy znaków,
InputString
jeśli są one obecne w połączonychascii_letters
idigits
ciągach. Następnie łączy listę razem w ciąg.źródło
Jako część innych odpowiedzi tutaj, oferuję naprawdę prosty i elastyczny sposób na zdefiniowanie zestawu znaków, do których chcesz ograniczyć zawartość łańcucha. W tym przypadku zezwalam na myślnik alfanumeryczny PLUS i podkreślenie. Po prostu dodaj lub usuń znaki z mojego,
PERMITTED_CHARS
jak pasuje do twojego przypadku użycia.źródło
string.digits + string.ascii_letters + '_-'
.SPECIAL_CHARS = '_-'
a następnie użyćstring.digits + string.ascii_letters + SPECIAL_CHARS
źródło
e for e in sent
i sprawdza poprzezif e.isalpha()
instrukcję, czy bieżący znak jest symbolem alfabetycznym, jeśli tak - łączy go zesent
zmienną przezsent = "".join()
i wszystkie symbole niealfabetyczne zostaną zastąpione""
(pusty ciąg), ponieważ zjoin
funkcji.źródło
Czasy losowych ciągów drukowalnych ASCII:
Wynik (Python 3.7):
str.maketrans
istr.translate
jest najszybszy, ale obejmuje wszystkie znaki spoza ASCII.re.compile
ipattern.sub
jest wolniejszy, ale jest jakoś szybszy niż''.join
&filter
.źródło
Jeśli dobrze zrozumiałem, najłatwiejszym sposobem jest użycie wyrażenia regularnego, ponieważ zapewnia ono dużą elastyczność, ale inną prostą metodą jest użycie pętli za kodem z przykładem. Policzyłem również występowanie słowa i zachowałem je w słowniku.
oceń to, jeśli ta odpowiedź jest przydatna!
źródło