Как декодировать символ Юникод в строку? - PullRequest
1 голос
/ 14 января 2020

У меня есть следующая строка:

Conversely, companies that aren\u0019t sharp-eyed enough to see that their real Dumbwaiter Pitches are lame, tired, or just plain evil \u0014 well, they usually end up facing extinction.

Эта строка содержит '\ u0019t'. Я не могу декодировать, потому что это уже строка. Если я сначала кодирую, а затем декодирую, он все равно показывает «\ u0019t». Как я могу получить это, чтобы показать '?

Ответы [ 2 ]

2 голосов
/ 14 января 2020

Один из вариантов - literal_eval:

import ast
s = r"Conversely, companies that aren\u0019t sharp-eyed enough to see that their real Dumbwaiter Pitches are lame, tired, or just plain evil \u0014 well, they usually end up facing extinction. \u2661"
r = ast.literal_eval(f'"{s}"')
print(r)

Вывод:

Conversely, companies that arent sharp-eyed enoughto see that their real Dumbwaiter Pitches are lame, tired, or just plain evil  well, they usually endup facing extinction. ♡
0 голосов
/ 14 января 2020

Каким-то образом escape-строка Unicode находится на расстоянии 2000 гекс от знака. Unicode da sh и апостроф:

Unicode-символ 'EM DA SH' (U + 2014)

и

Символ Unicode 'RIGHT SINGLE QUOTATION MARK' (U + 2019)

Так что давайте все равно исправим, даже если ошибка в источнике (ИМ), а не в пункте назначения:

import re
text = r'Conversely, companies that aren\u0019t sharp-eyed enough to see that their real Dumbwaiter Pitches are lame, tired, or just plain evil \u0014 well, they usually end up facing extinction.'
pattern = r'\\u([0-9a-fA-F]{4})'

# used to indicate the end of the previous match
# to save the string parts that don't need character encoding
off = 0
# start with an empty string
s = r''
# find and iterate over all matches of \uHHHH where H is a hex digit
for u in re.finditer(pattern, text):
    # append anything up to the unicode escape
    s += text[off:u.start()]
    # fix encoding mistake, unicode escapes are 2000 hex off the mark
    # then append it
    s += chr(int(u.group(1), 16) + 0x2000)
    # set off to the end of the match
    off = u.end()
# append everything from the last match to the end of the line
s += text[off:len(text)]
print(s)

распечатывает

Conversely, companies that aren’t sharp-eyed enough to see that their real Dumbwaiter Pitches are lame, tired, or just plain evil — well, they usually end up facing extinction.

Обратите внимание, что я с радостью проигнорировал любое возможное присутствие \\u00xx в тексте (где экранирован сам backsla sh), это то, что я оставлю для вас, чтобы решить. Любые правильные Unicode экранированные в тексте, конечно, также будут изменены.

...