Ich möchte überprüfen, ob eine Zeichenfolge in ASCII vorliegt oder nicht.
Ich bin mir ord()
jedoch bewusst , wenn ich es versuche ord('é')
, habe ich TypeError: ord() expected a character, but string of length 2 found
. Ich habe verstanden, dass dies durch die Art und Weise verursacht wird, wie ich Python erstellt habe (wie in ord()
der Dokumentation erläutert ).
Gibt es eine andere Möglichkeit zu überprüfen?
Antworten:
quelle
ord(c) < 128
ist unendlich lesbarer und intuitiver alsc <= "\x7F"
Ich denke, Sie stellen nicht die richtige Frage ...
Eine Zeichenfolge in Python hat keine Eigenschaft, die 'ascii', utf-8 oder einer anderen Codierung entspricht. Die Quelle Ihrer Zeichenfolge (unabhängig davon, ob Sie sie aus einer Datei lesen, über eine Tastatur eingeben usw.) hat möglicherweise eine Unicode-Zeichenfolge in ASCII codiert, um Ihre Zeichenfolge zu erstellen. Hier müssen Sie jedoch eine Antwort finden.
Vielleicht können Sie die Frage stellen: "Ist diese Zeichenfolge das Ergebnis der Codierung einer Unicode-Zeichenfolge in ASCII?" - Dies können Sie beantworten, indem Sie versuchen:
quelle
str
in Python 2,bytes
in Python 3).str
in jeder ISO-Codierung müsste zuerst in Unicode codiert werden. Die Antwort sollte darauf eingehen.s.decode('ascii') if isinstance(s, bytes) else s.encode('ascii')
in Python 3. Die Eingabe von OP ist ein Bytestring'é'
(Python 2-Syntax, Python 3 wurde zu diesem Zeitpunkt noch nicht veröffentlicht) und ist daher.decode()
korrekt.str
auf Python 2 ist ein Bytestring. Es ist richtig zu verwenden.decode('ascii')
, um herauszufinden, ob alle Bytes im ASCII-Bereich liegen.Python 3 Weg:
Übergeben Sie zur Überprüfung die Testzeichenfolge:
quelle
isascii
ist jetzt eine Funktion, bei der Sie eine Zeichenfolge übergeben:isascii('somestring')
==True
undisascii('àéç')
==False
try: s.encode('ascii'); return True
except UnicodeEncodeError: return False
(wie oben, aber Codierung, da Zeichenfolgen in Python 3 Unicode sind). Diese Antwort löst auch einen Fehler in Python 3 aus, wenn Sieisascii('\uD800')
False
Neu in Python 3.7 ( bpo32677 )
Keine lästig / ineffizient ascii Kontrollen auf Strings, neuen Einbau in
str
/bytes
/bytearray
Methode -.isascii()
wird überprüfen , ob die Saiten sind ascii.quelle
"\x03".isascii()
ist auch wahr. In der Dokumentation wird lediglich überprüft, ob alle Zeichen unter dem Codepunkt 128 (0-127) liegen. Wenn Sie auch Steuerzeichen vermeiden möchten, benötigen Sie :text.isascii() and text.isprintable()
. Die Verwendungisprintable
allein reicht ebenfalls nicht aus, da ein Zeichen wie ¿als (korrekt) druckbar angesehen wird, sich jedoch nicht im druckbaren Bereich von ASCII befindet. Sie müssen also beide überprüfen, wenn Sie beide möchten. Noch ein Problem: Leerzeichen gelten als druckbar, Tabulatoren und Zeilenumbrüche nicht.Bin kürzlich auf so etwas gestoßen - zum späteren Nachschlagen
die Sie verwenden könnten mit:
quelle
{'confidence': 0.99, 'encoding': 'EUC-JP'}
(was in diesem Fall völlig falsch war)Vincent Marchetti hat die richtige Idee, wurde jedoch
str.decode
in Python 3 nicht mehr unterstützt. In Python 3 können Sie denselben Test durchführen mitstr.encode
:Beachten Sie, dass sich die Ausnahme, die Sie abfangen möchten, ebenfalls von
UnicodeDecodeError
auf geändert hatUnicodeEncodeError
.quelle
bytes
Python 3 ohne.encode()
Methode ein)..decode()
in @Vincent Marchettis Antwort ist richtig .'é'
war zu der Zeit ein Test.Ihre Frage ist falsch; Der Fehler, den Sie sehen, ist nicht das Ergebnis der Erstellung von Python, sondern eine Verwechslung zwischen Byte-Strings und Unicode-Strings.
Byte-Strings (z. B. "foo" oder "bar" in der Python-Syntax) sind Sequenzen von Oktetten. Zahlen von 0-255. Unicode-Zeichenfolgen (z. B. u "foo" oder u'bar ') sind Sequenzen von Unicode-Codepunkten. Zahlen von 0-1112064. Sie scheinen jedoch an dem Zeichen é interessiert zu sein, das (in Ihrem Terminal) eine Mehrbyte-Sequenz ist, die ein einzelnes Zeichen darstellt.
ord(u'é')
Versuchen Sie stattdessen Folgendes:Das sagt Ihnen, welche Folge von Codepunkten "é" darstellt. Es kann Ihnen [233] geben, oder es kann Ihnen [101, 770] geben.
Anstatt
chr()
dies umzukehren, gibt esunichr()
:Dieses Zeichen kann tatsächlich entweder ein einzelner oder mehrere Unicode- "Codepunkte" sein, die selbst entweder Grapheme oder Zeichen darstellen. Es ist entweder "e mit einem akuten Akzent (dh Codepunkt 233)" oder "e" (Codepunkt 101), gefolgt von "einem akuten Akzent auf dem vorherigen Zeichen" (Codepunkt 770). So kann genau dieses Zeichen als Python-Datenstruktur
u'e\u0301'
oder dargestellt werdenu'\u00e9'
.Die meiste Zeit sollten Sie sich nicht darum kümmern müssen, aber es kann zu einem Problem werden, wenn Sie über eine Unicode-Zeichenfolge iterieren, da die Iteration nach Codepunkt und nicht nach zerlegbaren Zeichen funktioniert. Mit anderen Worten
len(u'e\u0301') == 2
undlen(u'\u00e9') == 1
. Wenn dies für Sie wichtig ist, können Sie mithilfe von zwischen zusammengesetzten und zerlegten Formularen konvertierenunicodedata.normalize
.Das Unicode-Glossar kann eine hilfreiche Anleitung zum Verständnis einiger dieser Probleme sein, indem aufgezeigt wird, wie sich die einzelnen Begriffe auf einen anderen Teil der Textdarstellung beziehen, was weitaus komplizierter ist, als viele Programmierer erkennen.
quelle
Wie wäre es damit?
quelle
Ich habe diese Frage gefunden, als ich versucht habe zu bestimmen, wie eine Zeichenfolge verwendet / codiert / decodiert wird, deren Codierung ich nicht sicher war (und wie Sonderzeichen in dieser Zeichenfolge maskiert / konvertiert werden).
Mein erster Schritt sollte darin bestehen, den Typ der Zeichenfolge zu überprüfen. Ich wusste dort nicht, dass ich von Typ (en) gute Daten über die Formatierung erhalten kann. Diese Antwort war sehr hilfreich und brachte meine Probleme auf den Punkt.
Wenn Sie unhöflich und hartnäckig werden
Stellen Sie insbesondere beim ENCODIEREN sicher, dass Sie nicht versuchen, eine Zeichenfolge zu unicodeieren (), die bereits Unicode ist. Aus irgendeinem schrecklichen Grund treten ASCII-Codec-Fehler auf. (Siehe auch das Python Kitchen-Rezept und die Python-Dokumentations- Tutorials, um besser zu verstehen, wie schrecklich dies sein kann.)
Schließlich entschied ich, dass ich Folgendes tun wollte:
Ebenfalls hilfreich beim Debuggen war das Setzen der Standardcodierung in meiner Datei auf utf-8 (setzen Sie diese an den Anfang Ihrer Python-Datei):
Auf diese Weise können Sie Sonderzeichen ('àéç') testen, ohne ihre Unicode-Escapezeichen (u '\ xe0 \ xe9 \ xe7') verwenden zu müssen.
quelle
Um Alexanders Lösung aus Python 2.6 (und in Python 3.x) zu verbessern, können Sie das Hilfsmodul curses.ascii und die Funktion curses.ascii.isascii () oder verschiedene andere verwenden: https://docs.python.org/2.6/ library / curses.ascii.html
quelle
curses.ascii
Sie können die Bibliothek für reguläre Ausdrücke verwenden, die die Posix-Standarddefinition [[: ASCII:]] akzeptiert.
quelle
Ein Stich (
str
-Typ) in Python besteht aus einer Reihe von Bytes. Es gibt keinen Weg anhand der Zeichenfolge zu erkennen, ob diese Reihe von Bytes eine ASCII-Zeichenfolge, eine Zeichenfolge in einem 8-Bit-Zeichensatz wie ISO-8859-1 oder eine mit UTF-8 oder UTF-16 oder was auch immer codierte Zeichenfolge darstellt .Wenn Sie jedoch die verwendete Codierung kennen, können Sie
decode
den str in einen Unicode-String umwandeln und dann mit einem regulären Ausdruck (oder einer Schleife) prüfen, ob er Zeichen außerhalb des Bereichs enthält, um den Sie sich Sorgen machen.quelle
Wie die Antwort von @ RogerDahl, aber es ist effizienter, einen Kurzschluss zu machen, indem die Zeichenklasse negiert und die Suche anstelle von
find_all
oder verwendet wirdmatch
.Ich stelle mir vor, dass ein regulärer Ausdruck dafür gut optimiert ist.
quelle
Um eine leere Zeichenfolge als ASCII einzuschließen, ändern Sie die
+
in*
.quelle
Um zu verhindern, dass Ihr Code abstürzt, möchten Sie möglicherweise ein
try-except
zum Abfangen verwendenTypeErrors
Beispielsweise
quelle
try
Wrapper ist völlig sinnlos. Wenn"¶"
es sich um eine Unicode-Zeichenfolge handelt,ord("¶")
funktioniert sie, und wenn dies nicht der Fall ist (Python 2),for c in s
wird sie in Bytes zerlegt, sodassord
sie weiterhin funktioniert.Ich benutze das Folgende, um festzustellen, ob der String ASCII oder Unicode ist:
Verwenden Sie dann einfach einen bedingten Block, um die Funktion zu definieren:
quelle
is_ascii(u'i am ascii')
. Obwohl die Buchstaben und Leerzeichen definitiv ASCII sind, kehrt dies immer noch zurück,False
weil wir die Zeichenfolge dazu gezwungen habenunicode
.