2008-11-18 6 views

Répondre

63

% uXXXX est un non-standard encoding scheme qui a été rejetée par le w3c, en dépit du fait qu'une mise en œuvre continue de vivre dans la terre JavaScript.

La technique la plus courante semble être de coder la chaîne UTF-8, puis% d'échapper les octets résultants en utilisant% XX. Ce programme est soutenu par urllib.unquote:

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

Malheureusement, si vous avez vraiment besoin pour soutenir% uXXXX, vous aurez probablement rouler votre propre décodeur. Sinon, il est probablement préférable de simplement encoder votre Unicode UTF-8, puis% d'échapper les octets qui en résultent.

Un exemple plus complet:

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

« urllib2.unquote » devrait être « urllib.unquote » – jamtoday

+0

Intéressant qu'un URI est un pour cent de byte codé chaîne, plutôt qu'une chaîne de caractères. – wberry

+0

@jamtoday pas nécessairement, en Python 2.7.5+ vous pouvez utiliser 'urllib2.unquote' juste essayer' imprimer (dir (urllib2)) ' –

9
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) 
6

Cela fera si vous devez absolument avoir ce (je ne vraiment d'accord avec les cris de « non standard »):

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 
+1

Un cas légèrement pathologique, mais: unquote_u ('Tan% 25u0131m') -> u'Tan \ u0131m 'plutôt que' Tan% u0131 'comme il se doit. Juste un rappel de pourquoi vous ne voulez probablement pas écrire un décodeur, sauf si vous en avez vraiment besoin. –

+0

Je suis totalement d'accord. C'est pourquoi je n'étais vraiment pas désireux d'offrir une solution réelle. Ces choses ne sont jamais si simples. L'O.P. aurait pu être désespérée cependant, et je pense que cela complète votre excellente réponse. –

4

Il y a un bogue dans la version ci-dessus où il flippe parfois quand il y a des caractères codés en ASCII et unicode dans la chaîne. Je pense que c'est spécifiquement quand il y a des caractères de la gamme supérieure 128 comme '\ xab' en plus de l'Unicode.

par ex. "% 5B% AB% u03E1% BB% 5D" provoque cette erreur.

J'ai trouvé si vous venez de faire les unicode d'abord, le problème a disparu:

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

\ xab n'est pas un caractère mais un octet. En effet votre exemple "chaîne" contient à la fois des octets et des caractères, ce qui n'est pas valable comme une seule chaîne dans n'importe quelle langue que je connaisse. – wberry

Questions connexes