Pracuję z plikiem .txt. Chcę ciąg tekstu z pliku bez znaków spoza zestawu ASCII. Chcę jednak zostawić spacje i kropki. W tej chwili też je rozdzieram. Oto kod:
def onlyascii(char):
if ord(char) < 48 or ord(char) > 127: return ''
else: return char
def get_my_string(file_path):
f=open(file_path,'r')
data=f.read()
f.close()
filtered_data=filter(onlyascii, data)
filtered_data = filtered_data.lower()
return filtered_data
Jak zmodyfikować onlyascii (), aby pozostawić spacje i kropki? Wyobrażam sobie, że nie jest to zbyt skomplikowane, ale nie mogę tego rozgryźć.
Odpowiedzi:
Możesz odfiltrować wszystkie znaki z ciągu, których nie można wydrukować, używając string.printable , na przykład:
string.printable na moim komputerze zawiera:
EDYCJA: W Pythonie 3 filtr zwróci iterowalny. Prawidłowy sposób na odzyskanie łańcucha to:
źródło
filter
jest to, że zwraca iterowalną. Jeśli potrzebujesz plecy string (jak ja, bo to potrzebne podczas wykonywania kompresji listy), a następnie to zrobić:''.join(filter(lambda x: x in string.printable, s)
.re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string)
. Zobacz ten wątek stackoverflow.com/a/20079244/658497Łatwym sposobem zmiany na inny kodek jest użycie metody encode () lub decode (). W twoim przypadku chcesz przekonwertować na ASCII i zignorować wszystkie symbole, które nie są obsługiwane. Na przykład szwedzka litera å nie jest znakiem ASCII:
Edytować:
Python3: str -> bajty -> str
Python2: unicode -> str -> unicode
Python2: str -> unicode -> str (dekoduj i koduj w odwrotnej kolejności)
źródło
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 27
s.decode('utf-8').encode('ascii', errors='ignore')
Według @artfulrobot powinno to być szybsze niż filter i lambda:
Zobacz więcej przykładów tutaj http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244
źródło
Twoje pytanie jest niejednoznaczne; pierwsze dwa zdania razem wzięte sugerują, że uważasz, że spacja i „kropka” nie są znakami ASCII. To jest niepoprawne. Wszystkie znaki takie, że ord (char) <= 127 są znakami ASCII. Na przykład twoja funkcja wyklucza te znaki! "# $% & \ '() * +, -. / Ale zawiera kilka innych, np. [] {}.
Cofnij się, pomyśl trochę i edytuj swoje pytanie, aby powiedzieć nam, co próbujesz zrobić, nie wspominając o słowie ASCII i dlaczego uważasz, że znaki takie, że ord (char)> = 128 są ignorowane. Ponadto: która wersja Pythona? Jakie jest kodowanie danych wejściowych?
Zwróć uwagę, że Twój kod odczytuje cały plik wejściowy jako pojedynczy ciąg, a Twój komentarz („świetne rozwiązanie”) do innej odpowiedzi sugeruje, że nie obchodzą Cię znaki nowej linii w danych. Jeśli twój plik zawiera dwie takie linie:
wynik byłby
'this is line 1this is line 2'
... czy tego naprawdę chcesz?Lepsze rozwiązanie obejmowałoby:
onlyascii
rozpoznanie, że funkcja filtrująca musi jedynie zwrócić prawdziwą wartość, jeśli argument ma zostać zachowany:
źródło
Możesz użyć następującego kodu, aby usunąć inne niż angielskie litery:
To wróci
źródło
Jeśli chcesz drukować znaki ascii, prawdopodobnie powinieneś poprawić swój kod, aby:
jest to odpowiednik
string.printable
(odpowiedź z @jterrace), z wyjątkiem braku zwrotów i tabulatorów ('\ t', '\ n', '\ x0b', '\ x0c' i '\ r'), ale nie odpowiada zakres na Twoje pytanieźródło
Przedzieram się przez Fluent Python (Ramalho) - gorąco polecam. Zrozumienie listy jednoliniowe, zainspirowane rozdziałem 2:
źródło