Wie kann man eine mit Backslash maskierte Zeichenfolge entsperren?

Lesezeit: 6 Minuten

Wie kann man eine mit Backslash maskierte Zeichenfolge entsperren
Nick

Angenommen, ich habe eine Zeichenfolge, die eine Backslash-escaped-Version einer anderen Zeichenfolge ist. Gibt es in Python eine einfache Möglichkeit, die Zeichenfolge zu entescapen? Ich könnte zum Beispiel machen:

>>> escaped_str=""Hello,\nworld!""
>>> raw_str = eval(escaped_str)
>>> print raw_str
Hello,
world!
>>> 

Dazu muss jedoch eine (möglicherweise nicht vertrauenswürdige) Zeichenfolge an eval() übergeben werden, was ein Sicherheitsrisiko darstellt. Gibt es eine Funktion in der Standardbibliothek, die eine Zeichenfolge übernimmt und eine Zeichenfolge ohne Auswirkungen auf die Sicherheit erzeugt?

  • Wenn Sie ein bestimmtes einzelnes Zeichen haben (wie 'n') Sie müssen nicht entkommen, wie ich es getan habe, Sie können es einfach tun s.replace('\n', 'n). Ich poste keine Antwort, weil die Frage allgemeiner ist, aber ich hatte ein ähnliches Problem und wollte mich nicht mit Bytes und Codierungen verkomplizieren, also stelle ich das hier einfach für andere …

    – Tomerikoo

    21. Juli 21 um 8:18 Uhr

>>> print '"Hello,\nworld!"'.decode('string_escape')
"Hello,
world!"

  • Gibt es etwas, das mit Python 3 kompatibel ist?

    – thejinx0r

    4. April 15 um 1:37 Uhr

  • @thejinx0r: schau mal hier: stackoverflow.com/questions/14820429/…

    – Christoph D

    7. April 15 um 8:34 Uhr

  • Grundsätzlich für Python3, das Sie wollen print(b"Hello,nworld!".decode('unicode_escape'))

    – Christoph D

    7. April 15 um 8:35 Uhr

  • Verwenden Sie für Python 3 value.encode('utf-8').decode('unicode_escape')

    – Casey Kuball

    18. August 18 um 14:36 ​​Uhr

  • WARNUNG: value.encode('utf-8').decode('unicode_escape') beschädigt Nicht-ASCII-Zeichen in der Zeichenfolge. Sofern die Eingabe nicht garantiert nur ASCII-Zeichen enthält, ist dies keine gültige Lösung.

    – Alex Peters

    9. Juni 19 um 11:46 Uhr

Sie können verwenden ast.literal_eval was sicher ist:

Evaluieren Sie sicher einen Ausdrucksknoten oder eine Zeichenfolge, die einen Python-Ausdruck enthält. Der bereitgestellte String oder Knoten darf nur aus den folgenden Python-Literalstrukturen bestehen: Strings, Zahlen, Tupel, Listen, Diktate, boolesche Werte und None. (ENDE)

So was:

>>> import ast
>>> escaped_str=""Hello,\nworld!""
>>> print ast.literal_eval(escaped_str)
Hello,
world!

  • Ein maskiertes Semikolon in der Zeichenfolge bricht diesen Code. Löst einen Syntaxfehler „unerwartetes Zeichen nach Zeilenfortsetzungszeichen“ aus

    – dunkler Himmel

    1. Juli 16 um 23:00 Uhr

  • @darksky beachte das ast Bibliothek erfordert Anführungszeichen (entweder " oder 'auch """ oder ''') um Ihre escaped_str, da es tatsächlich versucht, es als Python-Code auszuführen, aber die Sicherheit erhöht (verhindert das Einfügen von Zeichenfolgen).

    – InQβ

    4. Dezember 17 um 14:01 Uhr

  • @no1xsyzy: Was im Fall des OP bereits der Fall ist; Dies ist die richtige Antwort, wenn die str ist ein repr von a str oder bytes Objekt wie im Fall des OP; das unicode-escape Codec-Antwort ist für, wenn es kein ist reprsondern eine andere Form von Escape-Text (nicht in Anführungszeichen als Teil der Zeichenfolgendaten selbst eingeschlossen).

    – ShadowRanger

    18. August 18 um 2:55 Uhr

  • mit utf-8 chars geht das nicht. Überprüfen Sie die letzte Antwort mit dem Codepaket. es funktioniert tatsächlich.

    – rubmz

    12. September 19 um 18:31 Uhr

  • FWIW Ich habe versucht, einen entkommenen JSON-Text zu analysieren, und habe immer wieder diesen Fehler erhalten [ERROR] TypeError: string indices must be integers und diese Lösung hat funktioniert, um das zu lösen. Heben Sie die Maskierung der Zeichenfolge auf und parsen Sie sie dann als JSON.

    – Cyber-Mönch

    19. August 2020 um 17:43 Uhr

Wie kann man eine mit Backslash maskierte Zeichenfolge entsperren
Jesko Hüttenhain

Alle gegebenen Antworten werden bei allgemeinen Unicode-Strings unterbrochen. Folgendes funktioniert für Python3 in allen Fällen, soweit ich das beurteilen kann:

from codecs import encode, decode
sample = u'mon€y\nröcks'
result = decode(encode(sample, 'latin-1', 'backslashreplace'), 'unicode-escape')
print(result)

In neueren Python-Versionen funktioniert das auch ohne den Import:

sample = u'mon€y\nröcks'
result = sample.encode('latin-1', 'backslashreplace').decode('unicode-escape')

Wie in den Kommentaren beschrieben, können Sie auch die verwenden literal_eval Methode aus der ast Modul so:

import ast
sample = u'mon€y\nröcks'
print(ast.literal_eval(F'"{sample}"'))

Oder so, wenn Ihr String Ja wirklich enthält ein String-Literal (einschließlich der Anführungszeichen):

import ast
sample = u'"mon€y\nröcks"'
print(ast.literal_eval(sample))

Wenn Sie sich jedoch nicht sicher sind, ob die Eingabezeichenfolge doppelte oder einfache Anführungszeichen als Trennzeichen verwendet, oder wenn Sie nicht davon ausgehen können, dass sie überhaupt korrekt maskiert ist, dann literal_eval kann a erhöhen SyntaxError während die Kodierungs-/Dekodierungsmethode weiterhin funktioniert.

  • ast.literal_eval('"mon€y\nröcks"') == "mon€ynröcks" funktioniert gut für mich mit Python 3.7.3

    – obataku

    23. März 20 um 16:38 Uhr


  • Danke für den Kommentar @oldrinb! Ich habe die Antwort so bearbeitet, dass sie das enthält.

    – Jesko Hüttenhain

    23. März 20 um 18:56 Uhr

  • Ich glaube nicht, dass dies alle entkommenen UTF-8-Zeichenfolgen korrekt behandelt. zB beginnend mit s = '\xe7\xa7\x98'Python2 print s.decode('string-escape') Drucke wie ich hoffen würde, aber Ihre Antwort in Python3-Drucken ç§. Diese Antwort auf eine andere verwandte Frage in python3 scheint das zu tun, was ich erwarte: print(s.encode('latin-1').decode('unicode_escape').encode('latin-1').decode('utf-8')).

    – James

    9. Juni 21 um 18:40 Uhr


  • Hey @James, es kann keine universelle Lösung für Ihr Problem geben, die auch die “richtige” Codierung anwenden würde, da es keine Möglichkeit gibt, zu wissen, was das ist. In Ihrem Beispiel erwarten Sie UTF-8, aber wenn Sie beispielsweise CP1252 erwarten würden, würde Ihr Code eindeutig fehlschlagen. Allerdings – Wenn Sie meinen Code auf die Zeichenfolge anwenden s='\u79d8', erhalten Sie den gesuchten Charakter! Der Unterschied besteht darin, dass Ihre Eingabe die Escape-Version von ist seine utf8-Kodierungaber die Eingabe s='\u79d8' ist die entkommene Version von Schnur.

    – Jesko Hüttenhain

    13. Juni 21 um 1:13 Uhr

Wie kann man eine mit Backslash maskierte Zeichenfolge entsperren
Beutel

In Python3, str Objekte haben kein decode Methode und Sie müssen a verwenden bytes Objekt. Die Antwort von ChristopheD behandelt Python 2.

# create a `bytes` object from a `str`
my_str = "Hello,\nworld"
# (pick an encoding suitable for your str, e.g. 'latin1')
my_bytes = my_str.encode("utf-8")

# or directly
my_bytes = b"Hello,\nworld"

print(my_bytes.decode("unicode_escape"))
# "Hello,
# world"

Berücksichtigen Sie für Python3 Folgendes:

my_string.encode('raw_unicode_escape').decode('unicode_escape')

Der Codec „raw_unicode_escape“ codiert nach latin1, ersetzt aber zuerst alle anderen Unicode-Codepunkte durch ein Escapezeichen 'uXXXX' oder 'UXXXXXXXX' bilden. Wichtig ist, dass er sich vom normalen ‘unicode_escape’-Codec dadurch unterscheidet, dass er vorhandene Backslashes nicht berührt.

Wenn also der normale ‘unicode_escape’-Decoder angewendet wird, werden sowohl die neu maskierten Codepunkte als auch die ursprünglich maskierten Elemente gleich behandelt, und das Ergebnis ist eine native Unicode-Zeichenfolge ohne Maskierung.

(Der ‘raw_unicode_escape’-Decoder scheint nur auf die 'uXXXX' und 'UXXXXXXXX' Formulare, wobei alle anderen Escapezeichen ignoriert werden.)

Dokumentation:
https://docs.python.org/3/library/codecs.html?highlight=codecs#text-encodings

.

822350cookie-checkWie kann man eine mit Backslash maskierte Zeichenfolge entsperren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy