it-swarm.com.de

Wie kann ich Nicht-ASCII-Zeichen entfernen, aber mit Python Punkte und Leerzeichen lassen?

Ich arbeite mit einer .txt-Datei. Ich möchte eine Zeichenfolge aus der Datei ohne Nicht-ASCII-Zeichen. Ich möchte jedoch Leerzeichen und Perioden verlassen. Zur Zeit ziehe ich auch diese aus. Hier ist der 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

Wie kann ich nurascii () ändern, um Leerzeichen und Zeiträume zu hinterlassen? Ich kann mir vorstellen, dass es nicht zu kompliziert ist, aber ich kann es nicht verstehen.

76
user1120342

Sie können alle Zeichen aus der Zeichenfolge filtern, die nicht druckbar sind, indem Sie string.printable wie folgt verwenden:

>>> 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 auf meinem Rechner enthält:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
!"#$%&\'()*+,-./:;<=>[email protected][\\]^_`{|}~ \t\n\r\x0b\x0c
148
jterrace

Eine einfache Möglichkeit, zu einem anderen Codec zu wechseln, ist die Verwendung von encode () oder decode (). In Ihrem Fall möchten Sie in ASCII konvertieren und alle nicht unterstützten Symbole ignorieren. Beispielsweise ist der schwedische Buchstabe å kein ASCII - Zeichen:

    >>>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

Bearbeiten:

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 (dekodieren und kodieren in umgekehrter Reihenfolge)

>>> "hej d\xe5".decode("ascii", errors="ignore").encode()
'hej d'
64
Zweedeend

Laut @artfulrobot sollte dies schneller als Filter und Lambda sein:

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

Weitere Beispiele finden Sie hier http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20079244#20079244

19
Noam Manos

Ihre Frage ist mehrdeutig. Die ersten beiden Sätze zusammengenommen bedeuten, dass Leerzeichen und "Punkt" Zeichen sind, die keine ASCII-Zeichen sind. Das ist falsch. Alle Zeichen wie ord (char) <= 127 sind ASCII Zeichen. Zum Beispiel schließt Ihre Funktion diese Zeichen aus! "# $% &\'() * +, -. /, Enthält jedoch mehrere andere, beispielsweise [] {}.

Bitte treten Sie zurück, überlegen Sie sich etwas und bearbeiten Sie Ihre Frage, um uns mitzuteilen, was Sie zu tun versuchen, ohne das Wort ASCII zu erwähnen und warum Sie denken, dass Zeichen wie ord (char)> = 128 ignorierbar sind. Auch: welche Version von Python? Wie ist die Kodierung Ihrer Eingabedaten?

Bitte beachten Sie, dass Ihr Code die gesamte Eingabedatei als eine einzige Zeichenfolge liest, und Ihr Kommentar ("tolle Lösung") zu einer anderen Antwort impliziert, dass Sie sich nicht um Zeilenumbrüche in Ihren Daten kümmern. Wenn Ihre Datei zwei Zeilen wie folgt enthält:

this is line 1
this is line 2

das Ergebnis wäre 'this is line 1this is line 2' ... ist das, was Sie wirklich wollen?

Eine bessere Lösung wäre:

  1. ein besserer Name für die Filterfunktion als onlyascii 
  2. erkennung, dass eine Filterfunktion nur einen Wahrheitswert zurückgeben muss, wenn das Argument beibehalten werden soll:

    def filter_func(char):
        return char == '\n' or 32 <= ord(char) <= 126
    # and later:
    filtered_data = filter(filter_func, data).lower()
    
7
John Machin

Wenn Sie druckbare ASCII-Zeichen wünschen, sollten Sie Ihren Code wahrscheinlich folgendermaßen korrigieren:

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

dies ist äquivalent zu string.printable (Antwort von @Jterrace), abgesehen von den fehlenden Rücksendungen und Registerkarten ('\ t', '\ n', '\ x0b', '\ x0c' und '\ r'), entspricht aber nicht zum Bereich auf Ihre Frage

1
joaquin

Sie können den folgenden Code verwenden, um nicht englische Buchstaben zu entfernen:

import re
str = "123456790 ABC#%? .(朱惠英)"
result = re.sub(r'[^\x00-\x7f]',r'', str)
print(result)

Dies wird zurückkehren

123456790 ABC #%? . ()

1
Noha Elprince

Ich arbeite mich durch Fluent Python (Ramalho) - sehr empfehlenswert.

onlyascii = ''.join([s for s in data if ord(s) < 127])
onlymatch = ''.join([s for s in data if s in
              'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'])
0
Matthew Dunn