Konvertieren Sie eine Unicode-Zeichenfolge in eine Zeichenfolge in Python (mit zusätzlichen Symbolen).

504

Wie konvertiert man eine Unicode-Zeichenfolge (die zusätzliche Zeichen wie £ $ usw. enthält) in eine Python-Zeichenfolge?

williamtroup
quelle
2
Wir müssen wissen, welche Python-Version Sie verwenden und was Sie eine Unicode-Zeichenfolge aufrufen. Führen Sie die folgenden Schritte für einen kurzen unicode_string aus, der die Währungssymbole enthält, die die Störung verursachen: Python 2.x: print type(unicode_string), repr(unicode_string)Python 3.x: print type(unicode_string), ascii(unicode_string)Bearbeiten Sie dann Ihre Frage und kopieren Sie die Ergebnisse der obigen Druckanweisung. Geben Sie die Ergebnisse NICHT erneut ein. Suchen Sie auch oben in Ihrem HTML-Code nach, ob Sie Folgendes finden können: <meta http-equiv = "Inhaltstyp" content = "text / html; charset = iso-8859
John Machin
3
Ich bezweifle, dass Sie Unicode von einer Webanforderung erhalten. Sie erhalten wahrscheinlich UTF-8-codierten Unicode.
28
@lutz: Wie genau ist "UTF-8 codierter Unicode" kein Unicode?
Jalf
2
Sie sollten wirklich klarstellen, was Sie unter Unicode-Zeichenfolge und Python-Zeichenfolge verstehen (konkrete Beispiele wären meiner Meinung nach das Beste), da aus Kommentaren hervorgeht, dass Ihre Frage unterschiedlich interpretiert wird. Ich frage mich, warum Sie das nicht getan haben, obwohl es über 3,5 Jahre her ist, seit Sie diese Frage gestellt haben.
Piotr Dobrogost
6
@jalf: Wenn es codiert ist ; es ist nicht mehr Unicode zB,unicode_string = u"I'm unicode string"; bytestring = unicode_string.encode('utf-8'); unicode_again = bytestring.decode('utf-8')
jfs

Antworten:

573

Sehen unicodedata.normalize

title = u"Klüft skräms inför på fédéral électoral große"
import unicodedata
unicodedata.normalize('NFKD', title).encode('ascii', 'ignore')
'Kluft skrams infor pa federal electoral groe'
Sorantis
quelle
24
+1 beantwortet die Frage wie formuliert, @ williamtroups Problem, Unicode nicht in einer Datei speichern zu können, klingt nach einem ganz anderen Problem, das einer separaten Frage würdig ist
Mark Roddy
5
@ John - diese Antwort geht der Klärung des OP voraus.
Dominic Rodger
10
@ Mark Roddy: Seine Frage, wie geschrieben, ist, wie man eine "Unicode-Zeichenfolge" (was auch immer er damit meint), die einige Währungssymbole enthält, in eine "Python-Zeichenfolge" (was auch immer ...) konvertiert, und Sie denken, dass ein diakritisches Zeichen entfernt wird andere-nicht-ASCII-Zeichen löschen kludge beantwortet seine Frage ???
John Machin
13
@JohnMachin Dies beantwortet die Frage Wort für Wort: Die einzige Möglichkeit, eine unicodeZeichenfolge in eine zu konvertieren , strbesteht darin, die Zeichen, die in ASCII nicht dargestellt werden können, entweder zu löschen oder zu konvertieren. Also +1 von mir.
Izkata
4
@ lzkata: nein, das ist es nicht. type(title) == unicode and type(title.encode('utf-8')) == str. Sie müssen die Eingabe nicht beschädigen, um einen Bytestring zu erhalten, der in einer Datei gespeichert werden kann.
JFS
319

Sie können die Codierung in ASCII verwenden, wenn Sie die Nicht-ASCII-Zeichen nicht übersetzen müssen:

>>> a=u"aaaàçççñññ"
>>> type(a)
<type 'unicode'>
>>> a.encode('ascii','ignore')
'aaa'
>>> a.encode('ascii','replace')
'aaa???????'
>>>
Ferran
quelle
4
Tolle Antwort. Genau das, was ich brauchte. Auch tolle Präsentation, um die Wirkung von ignorevsreplace
Jonny Brooks
oder a.encode('ascii', 'xmlcharrefreplace')gibt 'aaa&#224;&#231;&#231;&#231;&#241;&#241;&#241;'.
Bob Stein
type(a)ist strin Python 3.6.8 und hat keine encode()Methode.
Ali Tou
138
>>> text=u'abcd'
>>> str(text)
'abcd'

Wenn die Zeichenfolge nur ASCII-Zeichen enthält.

igco
quelle
18
Dies würde nur unter Windows funktionieren. Und wird brechen, wenn es Nicht-ASCII-Symbole gibt.
Vanuan
6
Dies wird unterbrochen, wenn der Inhalt der Zeichenfolge tatsächlich Unicode ist und nicht nur ASCII-Zeichen in einer Unicode-Zeichenfolge. Tun Sie dies nicht, Sie erhalten überall zufällige UnicodeEncodeError-Ausnahmen.
Doug
11
Diese Antwort hat mir geholfen. Wenn Sie wissen, dass Ihre Zeichenfolge ASCII ist und Sie sie in eine Nicht-Unicode-Zeichenfolge zurückwandeln müssen, ist dies sehr nützlich.
VedTopkar
113

Wenn Sie eine Unicode-Zeichenfolge haben und diese in eine Datei oder ein anderes serialisiertes Formular schreiben möchten, müssen Sie sie zuerst in eine bestimmte Darstellung codieren , die gespeichert werden kann. Es gibt mehrere gängige Unicode-Codierungen, z. B. UTF-16 (verwendet zwei Bytes für die meisten Unicode-Zeichen) oder UTF-8 (je nach Zeichen 1 bis 4 Bytes / Codepunkt) usw. Um diese Zeichenfolge in eine bestimmte Codierung zu konvertieren, müssen Sie Kann benutzen:

>>> s= u'£10'
>>> s.encode('utf8')
'\xc2\x9c10'
>>> s.encode('utf16')
'\xff\xfe\x9c\x001\x000\x00'

Diese rohe Folge von Bytes kann in eine Datei geschrieben werden. Beachten Sie jedoch, dass Sie beim Zurücklesen wissen müssen, in welcher Codierung es sich befindet, und es mit derselben Codierung decodieren müssen.

Wenn Sie in Dateien schreiben, können Sie diesen manuellen Codierungs- / Decodierungsprozess mithilfe des Codecs- Moduls entfernen . Verwenden Sie zum Öffnen einer Datei, die alle Unicode-Zeichenfolgen in UTF-8 codiert , Folgendes:

import codecs
f = codecs.open('path/to/file.txt','w','utf8')
f.write(my_unicode_string)  # Stored on disk as UTF-8

Beachten Sie, dass alle anderen Benutzer dieser Dateien verstehen müssen, in welcher Codierung sich die Datei befindet, wenn sie sie lesen möchten. Wenn Sie der einzige sind, der das Lesen / Schreiben ausführt, ist dies kein Problem. Andernfalls stellen Sie sicher, dass Sie in einer Form schreiben, die für alle anderen Benutzer der Dateien verständlich ist.

In Python 3 ist diese Form des Dateizugriffs die Standardeinstellung. Die integrierte openFunktion verwendet einen Codierungsparameter und übersetzt immer in / von Unicode-Zeichenfolgen (das Standardzeichenfolgenobjekt in Python 3) für Dateien, die im Textmodus geöffnet werden.

Brian
quelle
58

Hier ist ein Beispiel:

>>> u = u'€€€'
>>> s = u.encode('utf8')
>>> s
'\xe2\x82\xac\xe2\x82\xac\xe2\x82\xac'
Bastien Léonard
quelle
1
Kann jemand erklären, warum, wenn ich das Euro-Symbol utf8wie hier gezeigt codiere, das Ergebnis nur Fragezeichen sind? Hier ist ein Bild von meinem Python, Version 2.7.13. (Ich kann andere Unicode-Objekte wie codieren u"Klüft", aber nicht die Euro?)
Die rote Erbse
5

Wenn Sie bereit / bereit sind, zu Python 3 zu wechseln (was möglicherweise nicht auf die Abwärtskompatibilität mit Python 2-Code zurückzuführen ist), müssen Sie keine Konvertierung durchführen. Der gesamte Text in Python 3 wird mit Unicode-Zeichenfolgen dargestellt. Dies bedeutet auch, dass die u'<text>'Syntax nicht mehr verwendet wird . Sie haben auch tatsächlich Byte-Zeichenfolgen, die zur Darstellung von Daten verwendet werden (die eine codierte Zeichenfolge sein können).

http://docs.python.org/3.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit

(Wenn Sie derzeit Python 3 verwenden, hängt das Problem wahrscheinlich damit zusammen, wie Sie versuchen, den Text in einer Datei zu speichern.)

JAB
quelle
2
In Python 3 sind Zeichenfolgen Unicode-Zeichenfolgen. Sie werden niemals verschlüsselt. Ich fand den folgenden Text nützlich: joelonsoftware.com/articles/Unicode.html
Er möchte es in einer Datei speichern. Wie hilft deine Antwort dabei?
John Machin
@lutz: Richtig, ich hatte vergessen, dass Unicode eher eine Zeichentabelle als eine Kodierung ist. @ John: Es gibt momentan nicht genügend Informationen, um zu wissen, wo das Problem beim Speichern liegt. Bekommt er einen Fehler? Bekommt er keine Fehler, aber wenn er die Datei extern öffnet, bekommt er Mojibake? Ohne diese Informationen könnten viel zu viele mögliche Lösungen bereitgestellt werden.
JAB
@Cat: Im Moment gibt es keine Informationen darüber, was er hat, geschweige denn, was sein Sparproblem ist. Ich habe ihn gebeten, einige Fakten anzugeben - siehe meine Antwort.
John Machin
5

Hier ist ein Beispielcode

import unicodedata    
raw_text = u"here $%6757 dfgdfg"
convert_text = unicodedata.normalize('NFKD', raw_text).encode('ascii','ignore')
Gihan Chathuranga
quelle
Wie unterscheidet sich diese Antwort von der akzeptierten Antwort?
Sgauri
3

Datei enthält Unicode-Zeichenfolge

\"message\": \"\\u0410\\u0432\\u0442\\u043e\\u0437\\u0430\\u0446\\u0438\\u044f .....\",

für mich

 f = open("56ad62-json.log", encoding="utf-8")
 qq=f.readline() 

 print(qq)                          
 {"log":\"message\": \"\\u0410\\u0432\\u0442\\u043e\\u0440\\u0438\\u0437\\u0430\\u0446\\u0438\\u044f \\u043f\\u043e\\u043b\\u044c\\u0437\\u043e\\u0432\\u0430\\u0442\\u0435\\u043b\\u044f\"}

(qq.encode().decode("unicode-escape").encode().decode("unicode-escape")) 
# '{"log":"message": "Авторизация пользователя"}\n'
Madjardi
quelle
2
es hat funktioniert, auch wenn ich nur benutze:result.encode().decode('unicode-escape')
Ammad Khalid
0

Für meinen Fall, in dem ich eine Zeichenfolgenvariable mit Unicode-Zeichen hatte, funktionierte keine Antwort, und keine hier erläuterte Codierung-Decodierung erledigte die Arbeit.

Wenn ich in einem Terminal mache

echo "no me llama mucho la atenci\u00f3n"

oder

python3
>>> print("no me llama mucho la atenci\u00f3n")

Die Ausgabe ist korrekt:

output: no me llama mucho la atención

Die Arbeit mit Skripten, die diese Zeichenfolgenvariable laden, funktionierte jedoch nicht.

Dies ist, was bei meinem Fall funktioniert hat , falls jemand hilft:

string_to_convert = "no me llama mucho la atenci\u00f3n"
print(json.dumps(json.loads(r'"%s"' % string_to_convert), ensure_ascii=False))
output: no me llama mucho la atención
pctripsesp
quelle
Sie müssen json
pctripsesp