Frage

Ich habe einen Unicode-String wie "Tanım", die als "Tan% u0131m" irgendwie codiert ist. Wie kann ich konvertieren diese kodierten String zurück zur ursprünglichen Unicode. Offenbar hat urllib.unquote nicht Unicode-Unterstützung.

War es hilfreich?

Lösung

% uXXXX ist ein Nicht-Standard-Kodierungsschema das gewesen ist abgelehnt von der w3c, trotz der Tatsache, dass eine Implementierung in JavaScript Land leben weiter.

Die üblichere Technik scheint die Zeichenfolge in UTF-8 zu sein, und dann zu entkommen% der resultierenden Bytes mit% XX. Dieses Schema wird durch urllib.unquote unterstützt:

>>> urllib2.unquote("%0a")
'\n'

Leider, wenn Sie wirklich Notwendigkeit % uXXXX unterstützen, werden Sie wahrscheinlich Ihre eigenen Decoder rollen. Ansonsten ist es wahrscheinlich weit mehr vorzuziehen, einfach UTF-8 kodieren Ihre Unicode und dann% entkommen die resultierenden Bytes sein.

Ein vollständigeres Beispiel:

>>> u"Tanım"
u'Tan\u0131m'
>>> url = urllib.quote(u"Tanım".encode('utf8'))
>>> urllib.unquote(url).decode('utf8')
u'Tan\u0131m'

Andere Tipps

def unquote(text):
    def unicode_unquoter(match):
        return unichr(int(match.group(1),16))
    return re.sub(r'%u([0-9a-fA-F]{4})',unicode_unquoter,text)

Dies wird es tun, wenn Sie unbedingt diese haben (ich wirklich mit den Schreien von „non-standard“ stimmen):

from urllib import unquote

def unquote_u(source):
    result = unquote(source)
    if '%u' in result:
        result = result.replace('%u','\\u').decode('unicode_escape')
    return result

print unquote_u('Tan%u0131m')

> Tanım

es ist ein Fehler in der obigen Version ist, wo es manchmal flippt aus, wenn es sowohl ASCII-Code und Unicode-codierte Zeichen in der Zeichenkette. Ich denke, die speziell wenn es Zeichen aus dem oberen 128 Bereich wie ‚\ xab‘ zusätzlich zu Unicode.

zB. "% 5B% AB% u03E1% BB% 5D" verursacht diesen Fehler.

Ich fand, wenn man nur die Unicode diejenigen zuerst tat, ging das Problem weg:

def unquote_u(source):
  result = source
  if '%u' in result:
    result = result.replace('%u','\\u').decode('unicode_escape')
  result = unquote(result)
  return result

Sie haben eine URL ein Nicht-Standard-Kodierungsschema von Normungsgremien abgelehnt, aber immer noch von einigem Encoder erzeugt werden. Die Funktion Python urllib.parse.unquote() können diese nicht verarbeiten.

Ihre eigenen Decoder zu schaffen, ist nicht so schwer, zum Glück. %uhhhh Einträge sollen sein UTF-16 Codepoints hier, also müssen wir nehmen Ersatzpaar berücksichtigt. Ich habe auch %hh Codepoints gemischt, für zusätzliche Verwirrung.

gesehen

, die mit im Auge, hier ist ein Decoder, der sowohl in Python 2 und Python funktioniert 3, vorausgesetzt, übergeben Sie in einem str Objekt in Python 3 (Python 2 Sorgen weniger):

try:
    # Python 3
    from urllib.parse import unquote
    unichr = chr
except ImportError:
    # Python 2
    from urllib import unquote

def unquote_unicode(string, _cache={}):
    string = unquote(string)  # handle two-digit %hh components first
    parts = string.split(u'%u')
    if len(parts) == 1:
        return parts
    r = [parts[0]]
    append = r.append
    for part in parts[1:]:
        try:
            digits = part[:4].lower()
            if len(digits) < 4:
                raise ValueError
            ch = _cache.get(digits)
            if ch is None:
                ch = _cache[digits] = unichr(int(digits, 16))
            if (
                not r[-1] and
                u'\uDC00' <= ch <= u'\uDFFF' and
                u'\uD800' <= r[-2] <= u'\uDBFF'
            ):
                # UTF-16 surrogate pair, replace with single non-BMP codepoint
                r[-2] = (r[-2] + ch).encode(
                    'utf-16', 'surrogatepass').decode('utf-16')
            else:
                append(ch)
            append(part[4:])
        except ValueError:
            append(u'%u')
            append(part)
    return u''.join(r)

Die Funktion wird stark von der aktuelle Standard-Bibliothek Implementierung .

Demo:

>>> print(unquote_unicode('Tan%u0131m'))
Tanım
>>> print(unquote_unicode('%u05D0%u05D9%u05DA%20%u05DE%u05DE%u05D9%u05E8%u05D9%u05DD%20%u05D0%u05EA%20%u05D4%u05D8%u05E7%u05E1%u05D8%20%u05D4%u05D6%u05D4'))
איך ממירים את הטקסט הזה
>>> print(unquote_unicode('%ud83c%udfd6'))  # surrogate pair
🏖
>>> print(unquote_unicode('%ufoobar%u666'))  # incomplete
%ufoobar%u666

Die Funktion auf Python arbeitet 2 (getestet auf 2,4-2,7) und Python 3 (getestet auf 3,3-3,8).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top