Comment puis-je supprimer les caractères non-ASCII, mais des périodes de congé et les espaces à l'aide de Python?
Je travaille avec un .fichier txt. Je veux une chaîne de texte à partir du fichier ayant pas de caractères non-ASCII. Cependant, je tiens à laisser des espaces et des périodes. À l'heure actuelle, je suis le décapage de ceux qui sont trop. Voici le code:
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
Comment dois-je modifier onlyascii() pour laisser des espaces et des périodes? J'imagine que c'est pas trop compliqué, mais je ne peux pas le comprendre.
- Merci (sincèrement) pour la clarification Jean. J'ai compris que des espaces et des périodes sont des caractères ASCII. Cependant, j'ai enlever les deux d'entre eux, involontairement, tout en essayant de supprimer uniquement les caractères non-ASCII. Je vois comment ma question risque implique le contraire.
- Votre problème est encore très sous-spécifiés. Voir ma réponse.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez filtrer tous les caractères de la chaîne qui ne sont pas imprimables à l'aide de chaîne de caractères.imprimable, comme ceci:
chaîne.imprimable sur ma machine contient:
chr(127) in string.printable
?if ord(char) < 48 or ord(char) > 127
. Sur mon deuxième commentaire, je suis en référence à '*' ,'(', et d'autres imprimable qui sont éliminés par l'OP...set(string.printable)
et ré-utiliser pour le filtrage. Aussi, ne pas filtrer l'ensemble du dossier à la fois - le faire dans des morceaux de 8K-512Kfilter
est qu'elle renvoie un objet iterable. Si vous avez besoin d'une chaîne de retour (comme je l'ai fait parce que j'avais besoin de ce lorsque vous faites la liste de compression), puis de le faire:''.join(filter(lambda x: x in string.printable, s)
.re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string)
. Voir ce fil stackoverflow.com/a/20079244/658497lambda x: x in printable
àprintable.__contains__
ferait courir plus vite; lalambda
signifie plus de Python code au niveau de l'exécution, alors en passant directement intégré dans la composition de la méthode de test supprime octet par caractère exécution de code.filter
lorsque vous utilisez le code ci-dessus. Étant donné que interprétations de la liste semblent être privilégiées serait, à l'aide de''.join(x for x in s if x in printable)
être un équivalent, et b) mieux?if
et de retrait de la deuxième ligne deif
commence juste après(
à partir de la première ligne.Un moyen facile de passer à un autre codec, est en utilisant encode() ou decode(). Dans votre cas, vous voulez les convertir en ASCII et ignorer tous les symboles qui ne sont pas pris en charge. Par exemple, le suédois lettre å n'est pas un caractère ASCII:
Edit:
Python3: str -> octets -> str
Python2: unicode -> str -> unicode
Python2: str -> unicode -> str (décoder et encoder dans l'ordre inverse)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 27
s.decode('utf-8').encode('ascii', errors='ignore')
Selon @artfulrobot, cela devrait être plus rapide que le filtre et lambda:
Voir plus d'exemples ici http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244
Votre question est ambiguë; les deux premières phrases, prises ensemble, implique que vous croyez que l'espace et de la "période" sont des caractères non-ASCII. Ceci est incorrect. Tous les caractères tels que ord(char) <= 127 caractères ASCII. Par exemple, votre fonction exclut ces caractères !"#$%&\'()*+,-./mais il inclut plusieurs autres, par exemple, [] {}.
Veuillez recul, de réfléchir un peu, et de modifier une question à nous dire ce que vous essayez de faire, sans mentionner le mot ASCII, et pourquoi vous pensez que les caractères tels que ord(char) >= 128, ignorable. Aussi: la version de Python? Qu'est-ce que l'encodage de vos données d'entrée?
Veuillez noter que votre code lit tout le fichier d'entrée comme une seule chaîne, et votre commentaire ("solution idéale") à une autre réponse, cela implique que vous ne vous souciez pas des retours à la ligne dans vos données. Si votre fichier contient les deux lignes comme ceci:
le résultat serait
'this is line 1this is line 2'
... est-ce que vous voulez vraiment?Une meilleure solution serait d'inclure:
onlyascii
reconnaissance d'une fonction de filtre a simplement besoin de retourner un truthy valeur si l'argument est d'être retenu:
Si vous voulez que des caractères ascii imprimables vous devriez corriger votre code:
c'est l'équivalent, pour
string.printable
(réponse de @jterrace), sauf pour l'absence de retours et les onglets ('\t','\n','\x0b','\x0c' et '\r'), mais ne correspondent à la portée de votre questionTravailler mon chemin à travers Couramment Python (Ramalho) - fortement recommandé.
Compréhension de liste un-ish-liners inspiré par le Chapitre 2: