Как удалить символы, отличные от ASCII, но оставить периоды и пробелы с помощью Python?
Я работаю с файлом .txt. Я хочу строку текста из файла без символов, отличных от ASCII. Однако я хочу оставить пробелы и периоды. В настоящее время я тоже их снимаю. Здесь код:
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
Как мне изменить onlyascii(), чтобы оставить пробелы и периоды? Я предполагаю, что это не слишком сложно, но я не могу понять.
Ответы
Ответ 1
Вы можете отфильтровать все символы из строки, которые нельзя распечатать, используя string.printable, например:
>>> s = "some\x00string. with\x15 funny characters"
>>> import string
>>> printable = set(string.printable)
>>> filter(lambda x: x in printable, s)
'somestring. with funny characters'
string.printable на моей машине содержит:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
!"#$%&\'()*+,-./:;<=>[email protected][\\]^_'{|}~ \t\n\r\x0b\x0c
ОБНОВЛЕНИЕ: В Python 3 фильтр будет возвращать итерацию. Правильный способ получить строку назад:
''.join(filter(lambda x: x in printable, s))
Ответ 2
Легкий способ изменить на другой кодек - это использовать encode() или decode(). В вашем случае вы хотите конвертировать в ASCII и игнорировать все символы, которые не поддерживаются. Например, шведская буква å не является символом ASCII:
>>>s = u'Good bye in Swedish is Hej d\xe5'
>>>s = s.encode('ascii',errors='ignore')
>>>print s
Good bye in Swedish is Hej d
Edit:
Python3: str → bytes → str
>>>"Hej då".encode("ascii", errors="ignore").decode()
'hej d'
Python2: unicode → str → unicode
>>> u"hej då".encode("ascii", errors="ignore").decode()
u'hej d'
Python2: str → unicode → str (декодировать и кодировать в обратном порядке)
>>> "hej d\xe5".decode("ascii", errors="ignore").encode()
'hej d'
Ответ 3
Согласно @artfulrobot, это должно быть быстрее, чем filter и lambda:
re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string)
Смотрите другие примеры здесь fooobar.com/questions/40584/...
Ответ 4
Ваш вопрос неоднозначен; первые два предложения, взятые вместе, подразумевают, что вы считаете, что пространство и "период" являются символами, отличными от ASCII. Это неверно. Все символы, такие, что ord (char) <= 127, являются символами ASCII. Например, ваша функция исключает эти символы! "# $% &\'() * +, -./Но включает в себя несколько других, например [] {}.
Пожалуйста, сделайте шаг назад, подумайте немного и отредактируйте свой вопрос, чтобы рассказать нам, что вы пытаетесь сделать, не упоминая слово ASCII, и почему вы думаете, что символы, такие как ord (char) >= 128, не знают, Также: какая версия Python? Какова кодировка ваших входных данных?
Обратите внимание, что ваш код считывает весь входной файл как одну строку, а ваш комментарий ( "большое решение" ) к другому ответу подразумевает, что вам не нужны строки в ваших данных. Если ваш файл содержит две строки:
this is line 1
this is line 2
результат будет 'this is line 1this is line 2'
... это то, что вы действительно хотите?
Большее решение будет включать:
- лучшее имя для функции фильтра, чем
onlyascii
-
распознавание того, что функция фильтра просто должна вернуть правдивое значение, если аргумент должен быть сохранен:
def filter_func(char):
return char == '\n' or 32 <= ord(char) <= 126
# and later:
filtered_data = filter(filter_func, data).lower()
Ответ 5
Если вам нужны печатные символы ascii, вероятно, вы должны исправить свой код:
if ord(char) < 32 or ord(char) > 126: return ''
это эквивалентно, string.printable
(ответ от @jterrace), за исключением отсутствия возвратов и вкладок ('\ t', '\n', '\ x0b', '\ x0c' и '\ r '), но не соответствует диапазону вашего вопроса
Ответ 6
Вы можете использовать следующий код для удаления неанглийских букв:
import re
str = "123456790 ABC#%? .(朱惠英)"
result = re.sub(r'[^\x00-\x7f]',r'', str)
print(result)
Это вернет
123456790 ABC#%?.()
Ответ 7
Работаем мой путь через Fluent Python (Ramalho) - настоятельно рекомендуется.
Перечислите понимание одноименных лайнеров, вдохновленных Главой 2:
onlyascii = ''.join([s for s in data if ord(s) < 127])
onlymatch = ''.join([s for s in data if s in
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'])