Хитрость здесь в том, чтобы использовать пользовательскую процедуру замены в re.sub
:
Если repl
является функцией, она вызывается для каждого неперекрывающегося вхождения pattern
. Функция принимает один аргумент объекта сопоставления и возвращает строку замены.
Чтобы преобразовать строку в печатные символы, кодирует ее в bytes
, используя latin1
, что сохраняет все буквенные байтовые коды, а затем декодирует это как UTF-8:
import re
text = r'Funda\195\131\194\167\195\131\194\163o'
print (bytes('Fundação','utf8')) # This is our target
print (bytes(re.sub (r'\\(\d+)', lambda x: chr(int(x.group(1))), text).encode('latin1')).decode('utf-8'))
Однако ваш текст не просто кодируется в UTF-8, а кодируется !
b'Funda\xc3\xa7\xc3\xa3o'
Fundação
, поэтому декодирование его в UTF-8 дает другую строку в кодировке UTF-8. Нам нужно перевести дважды :
# This first line prints the byte values so you can compare it to the UTF-8 target:
print (bytes(re.sub (r'\\(\d+)', lambda x: chr(int(x.group(1))), text).encode('latin1')).decode('utf-8').encode('latin1'))
print (bytes(re.sub (r'\\(\d+)', lambda x: chr(int(x.group(1))), text).encode('latin1')).decode('utf-8').encode('latin1').decode('utf8'))
, чтобы наконец получить вывод:
b'Funda\xc3\xa7\xc3\xa3o'
Fundação