1
# what I currently have 

print('你好') 

# 你好 

# this is what I want 

print('你好') 

# \uXXXX \uXXXX 

Wie mache ich das drucken? Ich möchte alle Nicht-ASCII-Zeichen in Strings als Unicode-Escape-Literale druckenWie Nicht-ASCII-Zeichen als uXXXX

+0

@jDo Was in Gottes Namen sagst du sogar? – AlanSTACK

+1

Strings in Python 3 sollten standardmäßig utf-8 verwenden. Die richtige Lösung ist, herauszufinden, warum Ihre Zeichenfolge in ASCII statt UTF-8 ist und das zu beheben. – Carpetsmoker

+0

@Alan Ja, ich weiß es nicht. Ich werde diesen nutzlosen Kommentar löschen: D Aber konnten Sie die Ausnahmebehandlung nicht auf diese Weise verwenden und die dumme Druckanweisung einfach durch etwas anderes ersetzen? (vorausgesetzt, dass Sie den Codierungsfehler nicht beheben möchten, wie Carpetsmoker vorschlägt) – jDo

Antwort

8

Sie können mit Nicht-ASCII, nicht druckbare Zeichen-Strings in eine Debug-Darstellung konvertieren konvertiert Sequenzen, die die ascii() function mit zu entkommen:

Geben Sie unter repr() eine Zeichenfolge zurück, die eine druckbare Darstellung eines Objekts enthält, aber die Nicht-ASCII-Zeichen in der Zeichenfolge repr() unter Verwendung von \x, \u oder \U escapes ausgibt.

Für Unicode-Codepunkte im Bereich U + 0100-U + FFFF verwendet dies \uhhhh Escapezeichen; für den Latin-1-Bereich (U + 007F-U + 00FF) \xhh werden stattdessen Escapes verwendet. Beachten Sie, dass die Ausgabe Syntax als gültige Python qualifiziert die Zeichenfolge neu zu erstellen, so Anführungszeichen enthalten sind:

>>> print('你好') 
你好 
>>> print(ascii('你好')) 
'\u4f60\u597d' 
>>> print(ascii('ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好')) 
'ASCII is not changed, Latin-1 (\xe5\xe9\xee\xf8\xfc) is, as are all higher codepoints, such as \u4f60\u597d' 

Wenn Sie Muss\uhhhh für alles haben, werden Sie Ihre eigene Umwandlung zu tun haben:

import re 

def escape_unicode(t, _p=re.compile(r'[\u0080-\U0010ffff]')): 
    def escape(match): 
     char = ord(match.group()) 
     return '\\u{:04x}'.format(char) if char < 0x10000 else '\\U{:08x}'.format(char) 
    return _p.sub(escape, t) 

die obige Funktion hat keine Anführungszeichen hinzufügen, wie die ascii() Funktion hat:

>>> print(escape_unicode('你好')) 
\u4f60\u597d 
>>> print(escape_unicode('ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好')) 
ASCII is not changed, Latin-1 (\u00e5\u00e9\u00ee\u00f8\u00fc) is, as are all higher codepoints, such as \u4f60\u597d 
+0

ist es möglich, aus Standardisierungsgründen alles zu "\ uXXXX" zu erzwingen? – AlanSTACK

+3

@Alan: nicht mit der Funktion 'ascii()'. Sie müssten das dann manuell tun. Beachten Sie auch, dass Sie für alles außerhalb der BMP (Codepunkte über U + FFFF) die Schreibweise "\ Uhhhhhhhh" in Python verwenden müssen. Welches Problem versuchen Sie zu lösen? –

2

Beachten Sie, dass, was, ohne \ mit \\ zu ersetzen, was Sie wollen, nicht reversibel ist; z.B. Sie können nicht wissen, ob die tatsächliche Zeichenfolge '好' (ein Zeichen) oder '\\u597d' (6 Zeichen in Ascii-Bereich) war, da beide \u597d als Ausgabe produzieren würden. Martijns Vorschlag macht den Backslash-Ersatz und ist reversibel.

Sie könnten nur die Umwandlung machen Sie sich selbst:

def unicodeescape(s): 
    return ''.join(c if ord(c) < 128 else '\\u%04x' % ord(c) for c in s) 

print(unicodeescape('你好')) 

(Martijn Anmerkung über Zeichen außerhalb der BMP gilt nach wie vor)

Wenn Sie dies alles, was das Programm Ausgänge tun wollen, und versucht sich zu erinnern alles durch eine Umwandlungsfunktion scheint nicht von einer guten Zeit wie Ihre Idee zu passieren, könnte man auch so etwas wie dies versucht:

import codecs, sys 

def unicodeescapereplace(error): 
    if isinstance(error, UnicodeEncodeError): 
     s = error.object[error.start:error.end] 
     repl = ''.join('\\u%04x' % ord(c) for c in s) 
     return (repl, error.end) 
    raise error 

codecs.register_error('unicodeescapereplace', unicodeescapereplace) 
sys.stdout = codecs.getwriter('ascii')(sys.stdout.buffer, 'unicodeescapereplace') 

print('你好') 

T Er erstellt einen benutzerdefinierten Codierungsfehlerhandler, der UnicodeEncodeErrors behandelt, indem er das problematische Zeichen durch einen Unicode-Escape ersetzt. Sie können es wie '你好'.encode('ascii', 'unicodeescapereplace') verwenden, oder ersetzen Sie das stdout wie im obigen Beispiel durch eines, das es automatisch für alle Codierung verwendet.

1

Die normale Darstellung wird durch die Verwendung der ascii, wie von Martijn Pieters erklärt, erhalten.

Wenn Sie wirklich constently drucken möchten \ u entkommt, können Sie es von Hand tun:

t = 'ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好' 
disp = u = "'" + ''.join([c if (ord(c) < 128) else r'\u%04x' % (ord(c),) for c in t ]) + "'" 
print(disp) 
print(eval(disp)) 

gibt wie erwartet:

'ASCII is not changed, Latin-1 (\u00e5\u00e9\u00ee\u00f8\u00fc) is, as are all higher codepoints, such as \u4f60\u597d' 
ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好 

NB: Ich weiß nicht, dass eval böse, aber in diesem speziellen Anwendungsfall weiß ich, dass die innere Zeichenfolge enthält keine ' und dass es in ' eingeschlossen ist, so dass es nicht mehr als eine bloße Umwandlung von codierten Zeichen sein kann - aber ich werde das nie auf einem externen tun String ohne mindestens t.contains("'") zu Testen ...

NB2: Diese Methode kann nicht korrekt Zeichen, dessen Code größer als 0xffff verarbeiten - es müsse eine andere wenn sonst ...