Comment puis-je supprimer des caractères non ASCII mais laisser des périodes et des espaces en utilisant Python?

je travaille avec A.fichier txt. Je veux une chaîne du texte du fichier sans caractères non-ASCII. Cependant, je veux 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 modifier onlyascii() pour laisser des espaces et des périodes? J'imagine que ce n'est pas trop compliqué, mais je n'arrive pas à le comprendre.

66
demandé sur alexwlchan 2011-12-31 22:23:44

6 réponses

vous pouvez filtrer tous les caractères de la chaîne qui ne sont pas imprimables en utilisant chaîne.imprimable , comme ceci:

>>> s = "some\x00string. with\x15 funny characters"
>>> import string
>>> printable = set(string.printable)
>>> filter(lambda x: x in printable, s)
'somestring. with funny characters'

de la chaîne.imprimable sur ma machine contient:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~ \t\n\r\x0b\x0c
133
répondu jterrace 2016-02-22 16:43:32

un moyen facile de passer à un codec différent, est d'utiliser encode() ou decode(). Dans votre cas, vous voulez convertir en ASCII et ignorer tous les symboles qui ne sont pas supportés. Par exemple, la lettre suédoise å n'est pas un caractère 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 -> octets -> 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 (décoder et encoder dans l'ordre inverse)

>>> "hej d\xe5".decode("ascii", errors="ignore").encode()
'hej d'
58
répondu Zweedeend 2017-07-26 10:10:19

selon @artfulrobot, cela devrait être plus rapide que le filtre et lambda:

re.sub(r'[^\x00-\x7f]',r'', your-non-ascii-string) 

Voir plus d'exemples ici http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244

17
répondu Noam Manos 2018-07-24 06:20:21

votre question est ambiguë; les deux premières phrases prises ensemble impliquent que vous croyez que l'espace et la "période" sont des caractères non-ASCII. Ceci est incorrect. Toutes les barres telles que ord (char) <= 127 sont des caractères ASCII. Par exemple, votre fonction exclut ces personnages !"#$%&\'()*+,-./ mais il inclut plusieurs autres, par exemple, [] {}.

veuillez prendre du recul, réfléchir un peu, et éditer votre question pour nous dire ce que vous essayez de faire, sans mentionner le mot ASCII, et pourquoi pensez-vous que les caractères tels que ord(char) >= 128 sont ignorables. Aussi: quelle version de Python? Quel est le codage de vos données d'entrée?

s'il vous plaît noter que votre code lit le fichier d'entrée entier comme une chaîne simple, et votre commentaire ("grande solution") à une autre réponse implique que vous ne vous souciez pas de nouvelles lignes dans vos données. Si votre fichier contient deux lignes comme ceci:

this is line 1
this is line 2

le résultat serait 'this is line 1this is line 2' ... est-ce que vous vraiment voulez?

une plus grande solution comprendrait:

  1. un meilleur nom pour la fonction de filtre que onlyascii
  2. reconnaissance qu'une fonction de filtre doit simplement retourner une valeur vraie si l'argument doit être conservé:

    def filter_func(char):
        return char == '\n' or 32 <= ord(char) <= 126
    # and later:
    filtered_data = filter(filter_func, data).lower()
    
7
répondu John Machin 2016-04-04 22:28:50

si vous voulez des caractères ASCII imprimables, vous devriez probablement corriger votre code à:

if ord(char) < 32 or ord(char) > 126: return ''

c'est l'équivalent de string.printable (réponse de @jterrace), sauf pour l'absence de retours et d'onglets ('\t', '\n','\x0b', '\x0c' et '\r') mais ne correspond pas à la fourchette sur votre question

1
répondu joaquin 2011-12-31 19:11:46

travailler mon chemin à travers Python Fluent (Ramalho) - fortement recommandé. Liste de compréhension liners à un ish inspirés du Chapitre 2:

onlyascii = ''.join([s for s in data if ord(s) < 127])
onlymatch = ''.join([s for s in data if s in
              'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'])
0
répondu Matthew Dunn 2017-09-14 19:14:52