Как правильно декодировать escape-последовательность в строке, записанной в десятичном виде - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть фрагмент кода, который содержит строки с escape-последовательностями UTF-8, записанными в десятичном виде, например

my_string = "Hello\035"

, которые затем следует интерпретировать как

Hello#

Я надеваюне против разбора десятичного значения, до сих пор я использовал такие вещи для всей строки, и это, кажется, работает лучше всего (без ошибок и что-то делает):

print(codecs.escape_decode(my_string)[0].decode("utf-8"))

Но нумерация кажется довольноoff, потому что я должен использовать escape-последовательность \ 043, чтобы правильно декодировать hastag (#), и он одинаков для всех остальных символов.

1 Ответ

0 голосов
/ 25 февраля 2019

Вы не можете однозначно обнаружить и заменить все escape-последовательности \ooo из строкового литерала, потому что эти escape-последовательности безвозвратно заменены соответствующими им символьными значениями до того, как ваша первая строка кода будет выполнена.Что касается Python, "foo\041" и "foo!" идентичны на 100%, и невозможно определить, что первый объект был определен с помощью escape-последовательности, а последний - нет.

Если выиметь некоторую гибкость в отношении формы входных данных, тогда вы все равно сможете делать то, что вы хотите.Например, если вам разрешено использовать необработанные строки вместо обычных строк, то r"Hello\035" не будет интерпретироваться как «Hello, сопровождаемый хэш-тегом» до времени выполнения.Это будет интерпретировано как «Hello, сопровождаемый обратной косой чертой, сопровождаемый 0 3 и 5»Поскольку цифровые символы по-прежнему доступны, вы можете манипулировать ими в своем коде.Например,

import re

def replace_decimal_escapes(s):
    return re.sub(
        #locate all backslashes followed by three digits
        r"\\(\d\d\d)",
        #fetch the digit group, interpret them as decimal integer, then get cooresponding char
        lambda x: chr(int(x.group(1), 10)), 
        s
    )

test_strings = [
    r"Hello\035",
    r"foo\041",
    r"The \040quick\041 brown fox jumps over the \035lazy dog"
]

for s in test_strings:
    result = replace_decimal_escapes(s)
    print("input:  ", s)
    print("output: ", result)

Результат:

input:   Hello\035
output:  Hello#
input:   foo\041
output:  foo)
input:   The \040quick\041 brown fox jumps over the \035lazy dog
output:  The (quick) brown fox jumps over the #lazy dog

В качестве бонуса этот подход также работает, если вы получаете входные строки через input(), поскольку обратные слеши набираются в этом приглашениипользователь не интерпретируется как escape-последовательности.Если вы введете print(replace_decimal_escapes(input())) и пользователь введет «Hello \ 035», то при желании на выходе будет «Hello #».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...