Muszę zastąpić wszystkie znaki spoza ASCII (\ x00- \ x7F) spacją. Dziwi mnie, że w Pythonie nie jest to łatwe, chyba że czegoś mi brakuje. Następująca funkcja po prostu usuwa wszystkie znaki spoza ASCII:
def remove_non_ascii_1(text):
return ''.join(i for i in text if ord(i)<128)
I ten zastępuje znaki spoza ASCII ilością spacji odpowiadającą liczbie bajtów w punkcie kodu znaku (tzn. –
Znak jest zastępowany 3 spacjami):
def remove_non_ascii_2(text):
return re.sub(r'[^\x00-\x7F]',' ', text)
Jak mogę zastąpić wszystkie znaki spoza ASCII pojedynczą spacją?
Od tej niezliczonej o podobnej SO pytania , żaden adres charakter zamiennych w przeciwieństwie do rozbiórki , a dodatkowo nie uwzględniają wszystkich znaków spoza ASCII specyficzny charakter.
–
. To ten facet .Odpowiedzi:
Twoje
''.join()
wyrażenie filtruje , usuwając wszystko inne niż ASCII; zamiast tego możesz użyć wyrażenia warunkowego:To obsługuje znaki jeden po drugim i nadal używałoby jednego miejsca na zastąpioną postać.
Twoje wyrażenie regularne powinno po prostu zastąpić kolejne znaki spoza ASCII spacją:
Uwaga
+
tam.źródło
str.join()
potrzebuje listy (dwukrotnie przejdzie przez wartości), a wyrażenie generatora zostanie najpierw przekonwertowane na jedno. Zrozumienie listy jest po prostu szybsze. Zobacz ten post .–
znak jest zastąpiony 3 spacjami” w pytaniu oznacza, że wejście jest bajtowaniem (nie Unicode) i dlatego używany jest Python 2 (inaczej''.join
by się nie udał ). Jeśli OP chce pojedynczej spacji na kodod Unicode, wówczas dane wejściowe należy najpierw zdekodować do Unicode.Dla uzyskania najbardziej podobnej reprezentacji oryginalnego ciągu polecam moduł unidecode :
Następnie możesz użyć go w ciągu:
źródło
דותן
. Jednak w ogólnym znaczeniu jest to świetne, dziękuję!Do przetwarzania znaków użyj ciągów Unicode:
Ale zauważ, że nadal będziesz mieć problem, jeśli Twój ciąg znaków zawiera rozłożone znaki Unicode (na przykład oddzielny znak i łączące znaki akcentu):
źródło
ud.normalize('NFC',s)
do łączenia znaków, ale nie wszystkie kombinacje kombinacji są reprezentowane przez pojedyncze punkty kodowe. Potrzebowałbyś mądrzejszego rozwiązania, patrząc naud.category()
postać.\X
(rozszerzony klaster grafemowy) regex (obsługiwany przezregex
moduł) pozwala na iterację takich znaków (uwaga: „grafemy niekoniecznie łączą sekwencje znaków, a łączenie sekwencji znaków niekoniecznie jest grafem” ).Jeśli zamiennym znakiem może być „?” zamiast spacji sugerowałbym
result = text.encode('ascii', 'replace').decode()
:Wyniki:
źródło
A co z tym?
źródło
Jako natywne i wydajne podejście, nie musisz używać
ord
ani zapętlać znaków. Wystarczy zakodowaćascii
i zignorować błędy.Poniższe po prostu usunie znaki inne niż ascii:
Teraz, jeśli chcesz zastąpić usunięte znaki, wykonaj następujące czynności:
źródło
encode
zwróci to bajtowanie, więc miej to na uwadze. Ponadto ta metoda nie usuwa znaków takich jak znak nowej linii.Potencjalnie na inne pytanie, ale podaję moją wersję odpowiedzi @ Alvero (używając unidecode). Chcę zrobić „zwykły” pasek na moich ciągach, tj. Początek i koniec mojego ciągu dla białych znaków, a następnie zastąpić tylko inne znaki białych znaków „zwykłą” spacją, tj.
do
,
Najpierw zamieniamy wszystkie spacje inne niż Unicode spacją zwykłą (i łączymy ją ponownie),
A potem dzielimy to ponownie, normalnym podziałem Pythona, i usuwamy każdy „bit”,
I w końcu dołącz do nich ponownie, ale tylko wtedy, gdy ciąg minie
if
test,I dzięki temu
safely_stripped('ㅤㅤㅤㅤCeñíaㅤmañanaㅤㅤㅤㅤ')
poprawnie zwraca'Ceñía mañana'
.źródło