2010-10-15 18 views
1

J'ai une chaîne. Il ressemble à s = 'e6b693e6a0abe699ab'. Je veux mettre un signe de pourcentage devant chaque paire de caractères, donc percentEncode(s) == '%e6%b6%93%e6%a0%ab%e6%99%ab'.Transformer une chaîne hexadécimale en chaîne codée en pourcentage en Python

Quelle est une bonne façon d'écrire percentEncode(s)?

(Remarque, je ne foutais que unreserved characters ne sont pas convertis en ASCII.)

Je peux penser à de grands moyens verbeux de le faire, mais je veux quelque chose de gentil et simple, et pendant que je suis assez nouveau pour Python, je serais surpris si Python ne pouvait pas le faire gentiment.

+0

Est-ce que par hasard vous voulez pour aboutir à 's.decode ('hex')'? – tzot

+0

@ ΤΖΩΤΖΙΟΥ - nah, 's.decode ('hex')' transforme une chaîne de caractères de 8 bits en représentation hexadécimale. Je l'utilise déjà pour créer 's'. –

+0

effectivement, ce que vous décrivez est 's.encode ('hex')', mais vous avez répondu à ma question si vous en avez besoin :) – tzot

Répondre

2
>>> ''.join("%"+i+s[n+1] for n,i in enumerate(s) if n%2==0) 
'%e6%b6%93%e6%a0%ab%e6%99%ab' 

Ou en utilisant re

>>> import re 
>>> re.sub("(..)","%\\1",s) 
'%e6%b6%93%e6%a0%ab%e6%99%ab' 
+0

J'aime la solution regex. Vous avez également trouvé un bogue dans SO - avant de l'éditer, la première méthode affichée sous forme de code dans l'aperçu JS, mais sous forme de citation dans la version rendue par le serveur. –

2

Oh, vous voulez dire:

''.join(["%%%s" % pair for pair in [s[i:i+2] for i in range(0,len(s),2)]]) 

Bien que probablement si vous faites cela pour url échapper ou quelque chose comme, il y a une fonction de bibliothèque plus appropriée à votre usage.

Edité pour ajouter - puisque tout le monde aime une solution itertools mignonne:

>>> from itertools import izip, cycle 
>>> its = iter(s) 
>>> tups = izip(cycle('%'), its, its) 
>>> ''.join(''.join(t) for t in tups) 
'%e6%b6%93%e6%a0%ab%e6%99%ab' 
+0

cycle ('%') fournira la même chose, puisque '' sont itérables. – kevpie

+0

Merci @kevpie, incorporé ceci. – tcarobruce

1

utiliser une expression rationnelle à l'effet de /([0-9a-f]{2})/ig et le remplacer par %\1

2

Au hasard que vous faites URL- encodage manuellement, vous voudrez peut-être lire ceci blog post. Il explique comment faire cela en utilisant la fonction quote_plus du module urllib de la bibliothèque standard.

1

Juste pour être académique.

Essayez d'utiliser autant d'itérateurs que possible.

s = 'e6b693e6a0abe699ab' 

from itertools import islice, izip, cycle, chain 

def percentEncode(s): 
    percentChars = cycle('%') 
    firstChars = islice(s,0,None, 2) 
    secondChars = islice(s,1,None, 2) 
    return ''.join(chain.from_iterable(izip(percentChars, firstChars, secondChars))) 


if __name__ == '__main__': 
    print percentEncode(s) 

Merci à @tcarobruce pour le rappel de réutiliser la chaîne iter.

s = 'e6b693e6a0abe699ab' 

from itertools import islice, izip, cycle, chain 

def percentEncode(s): 
    iter_s = iter(s) 
    return ''.join(chain.from_iterable(izip(cycle('%'), iter_s, iter_s))) 

if __name__ == '__main__': 
    print percentEncode(s) 
1

D'après un commentaire de la vôtre dans la question initiale, si à partir de la chaîne initiale initial_s avant son encodage en hexadécimal, vous pouvez avoir le résultat que:

def percent_encode(initial_s): 
    return ''.join('%%%02x' % ord(c) for c in initial_s) 

>>> percent_encode('hello') 
'%68%65%6c%6c%6f'