Zastąp znaki inne niż ASCII pojedynczym spacją
Muszę zastąpić wszystkie znaki spoza ASCII (\x00-\x7f) spacją. Dziwię się, że w Pythonie nie jest to łatwe, chyba że coś przeoczyłem. Poniższa 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 nie-ASCII ilością spacji zgodnie z ilością bajtów w punkcie kodu znaku (tzn. znak –
zastępuje się 3 spacjami):
def remove_non_ascii_2(text):
return re.sub(r'[^\x00-\x7F]',' ', text)
Jak mogę zastąpić wszystkie znaki spoza ASCII pojedyncza przestrzeń?
Z na myriad z podobne więc pytania, Brak adres charakter wymiana jako przeciw na rozbieranie, i dodatkowo adresuje wszystkie znaki spoza ascii, a nie konkretny znak.
6 answers
Twoje ''.join()
wyrażenie to filtrowanie , Usuwanie czegokolwiek innego niż ASCII; zamiast tego możesz użyć wyrażenia warunkowego:
return ''.join([i if ord(i) < 128 else ' ' for i in text])
To obsługuje znaki jeden po drugim i nadal używa jednego spacji na znak zastąpiony.
Twoje Wyrażenie regularne powinno zastąpić kolejne znaki spoza ASCII spacją:
re.sub(r'[^\x00-\x7F]+',' ', text)
Zwróć uwagę na +
tam.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-19 18:11:35
Dla Ciebie najbardziej podobna reprezentacja oryginalnego ciągu polecam moduł unidecode :
from unidecode import unidecode
def remove_non_ascii(text):
return unidecode(unicode(text, encoding = "utf-8"))
Następnie możesz użyć go w ciągu znaków:
remove_non_ascii("Ceñía")
Cenia
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 17:58:00
Do przetwarzania znaków Użyj ciągów Unicode:
PythonWin 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32.
>>> s='ABC马克def'
>>> import re
>>> re.sub(r'[^\x00-\x7f]',r' ',s) # Each char is a Unicode codepoint.
'ABC def'
>>> b = s.encode('utf8')
>>> re.sub(rb'[^\x00-\x7f]',rb' ',b) # Each char is a 3-byte UTF-8 sequence.
b'ABC def'
Ale pamiętaj, że nadal będziesz miał 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):
>>> s = 'mañana'
>>> len(s)
6
>>> import unicodedata as ud
>>> n=ud.normalize('NFD',s)
>>> n
'mañana'
>>> len(n)
7
>>> re.sub(r'[^\x00-\x7f]',r' ',s) # single codepoint
'ma ana'
>>> re.sub(r'[^\x00-\x7f]',r' ',n) # only combining mark replaced
'man ana'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-19 21:26:15
Jeśli znak zastępczy może być '?'zamiast spacji proponuję result = text.encode('ascii', 'replace').decode()
:
"""Test the performance of different non-ASCII replacement methods."""
import re
from timeit import timeit
# 10_000 is typical in the project that I'm working on and most of the text
# is going to be non-ASCII.
text = 'Æ' * 10_000
print(timeit(
"""
result = ''.join([c if ord(c) < 128 else '?' for c in text])
""",
number=1000,
globals=globals(),
))
print(timeit(
"""
result = text.encode('ascii', 'replace').decode()
""",
number=1000,
globals=globals(),
))
Wyniki:
0.7208260721400134
0.009975979187503592
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-03 11:12:33
A co z tym?
def replace_trash(unicode_string):
for i in range(0, len(unicode_string)):
try:
unicode_string[i].encode("ascii")
except:
#means it's non-ASCII
unicode_string=unicode_string[i].replace(" ") #replacing it with a single space
return unicode_string
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-20 22:35:18
Jako natywne i efektywne podejście, nie musisz używać ord
ani żadnej pętli nad znakami. Wystarczy zakodować za pomocą ascii
i zignorować błędy.
Poniższe po prostu usunie znaki spoza ascii:
new_string = old_string.encode('ascii',errors='ignore')
Teraz, jeśli chcesz zastąpić usunięte znaki, wykonaj następujące czynności:
final_string = new_string + b' ' * (len(old_string) - len(new_string))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 14:39:32