2010-10-15 5 views
1

У меня есть строка. Похоже, s = 'e6b693e6a0abe699ab'.Поверните шестнадцатеричную строку в строку, закодированную в процентах, в Python

Я хочу поставить знак процента перед каждой парой символов, поэтому percentEncode(s) == '%e6%b6%93%e6%a0%ab%e6%99%ab'.

Что такое хороший способ написания percentEncode(s)?

(Обратите внимание, что я не забочусь, что unreserved characters не преобразуются в ASCII.)

я могу думать о больших многословных способов сделать это, но я хочу что-то хорошее и простое, и в то время как я довольно новый для Python, я был бы удивлен, если Python не сможет сделать это красиво.

+0

ли вы случайно хотите для результата 's.decode ('hex')'? – tzot

+0

@ ΤΖΩΤΖΙΟΥ - nah, 's.decode ('hex')' превращает строку из 8 бит символов в шестнадцатеричное представление ее. Я на самом деле уже использую его для создания 's'. –

+0

На самом деле, что вы описываете, это 's.encode ('hex')', но вы ответили на мой вопрос, нужно ли вам это :) – tzot

ответ

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' 

Или используя повторно

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

Мне нравится решение регулярного выражения. Вы также обнаружили ошибку в SO - до того, как я ее отредактировал, первый метод, отображаемый как код в предварительном просмотре JS, но как цитату в версии, предоставленной сервером. –

2

О, вы имеете в виду:

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

Хотя, возможно, если вы делаете это для URL побега или некоторые такие, есть функция библиотеки больше подходит к вашему использованию.

Edited добавить - так как все любят симпатичное решение itertools:

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

цикл ('%') будет обеспечивать одно и то же, так как '' истребимы. – kevpie

+0

Спасибо @kevpie, включил это. – tcarobruce

1

Используйте Regex для эффекта /([0-9a-f]{2})/ig и заменить с %\1

2

На случай, если вы делаете url- кодирование вручную, вы можете прочитать это blog post. В нем объясняется, как это сделать, используя функцию urllib в стандартной библиотеке библиотеки для функции quote_plus.

1

Просто быть академическим.

Пытается использовать как можно больше итераторов.

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) 

Благодаря @tcarobruce для напоминания о повторном использовании строки 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

Основываясь на комментарии твоих в первоначальном вопросе, если начиная с исходной строки initial_s перед его кодированием в шестнадцатеричный, вы можете получить результат как:

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

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