Jak odznaczyć urlencoded ciąg unicode w Pythonie?

Mam ciąg unicode jak "Tanım", który jest zakodowany jako" Tan%u0131m " jakoś. Jak mogę przekonwertować ten zakodowany ciąg z powrotem do oryginalnego unicode. Najwyraźniej urllib.unquote nie obsługuje unicode.

Author: smci, 2008-11-19

4 answers

%uXXXX jest niestandardowym schematem kodowania , który został odrzucony przez w3c, pomimo faktu, że implementacja nadal żyje w środowisku JavaScript.

Bardziej powszechną techniką wydaje się być UTF-8 zakodowanie ciągu znaków, a następnie % escape wynikowych bajtów za pomocą %XX. ten schemat jest obsługiwany przez urllib.unquote:

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

Niestety, jeśli naprawdę potrzebujesz do obsługi %uXXXX, prawdopodobnie będziesz musiał włączyć własny dekoder. W przeciwnym razie prawdopodobnie aby być o wiele bardziej korzystnym, wystarczy UTF-8 zakodować unicode, a następnie % escape wynikowych bajtów.

Bardziej kompletny przykład:

>>> u"Tanım"
u'Tan\u0131m'
>>> url = urllib.quote(u"Tanım".encode('utf8'))
>>> urllib.unquote(url).decode('utf8')
u'Tan\u0131m'
 66
Author: Aaron Maenpaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 23:22:44
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)
 10
Author: Markus Jarderot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 23:22:24

To wystarczy, jeśli absolutnie musisz to mieć (naprawdę zgadzam się z okrzykami "niestandardowego"):

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
 6
Author: Ali Afshar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-18 23:32:49

Jest błąd w powyższej wersji, gdzie czasami się dziwi, gdy w łańcuchu są zarówno znaki zakodowane ascii, jak i Unicode. Myślę, że jest to szczególnie, gdy istnieją znaki z górnego zakresu 128, takie jak '\xab' oprócz unicode.

Np. "%5B%AB%u03E1%BB%5D " powoduje ten błąd.

Znalazłem, że jeśli najpierw zrobisz unicode, problem zniknął:

def unquote_u(source):
  result = source
  if '%u' in result:
    result = result.replace('%u','\\u').decode('unicode_escape')
  result = unquote(result)
  return result
 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-16 03:13:58