【问题标题】:How to decode escape sequence in string written in decimal properly如何正确解码以十进制编写的字符串中的转义序列
【发布时间】:2019-07-18 21:31:41
【问题描述】:

我有一段代码,其中包含用十进制编写的 UTF-8 转义序列的字符串,例如

my_string = "Hello\035"

这应该被解释为

Hello#

我不介意解析十进制值,到目前为止,我已经对整个字符串使用了这样的东西,这似乎效果最好(没有错误并且做了一些事情):

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

但是编号似乎很不正确,因为我必须使用 \043 转义序列才能正确解码 hastag (#),并且所有其他字符都是相同的。

【问题讨论】:

  • 这些转义序列从何而来?发件人可能不知道 Python 将字符串中的反斜杠和三位数字解释为 octal 值,而不是十进制值。也许如果你消除了这个困惑,那么他们会很乐意使用 043(它是 35 的八进制形式)来表示一个哈希标签。
  • 这是一个学校项目,我们必须能够处理这样的输入:\xyz,范围是从000到999,但它是十进制,而不是八进制
  • @Sandeep 是的,我知道这一点,但我得到了十进制的转义序列,因为这是一个学校项目,即使我想要,我也无法将输入更改为更合理的值到
  • @Sandeep:OP 知道我的想法。问题是当它用十进制写时如何处理。
  • ... 如果是 input 值,情况就不同了。在这种情况下,您可以获得单个字符,并且可以解析该输入。

标签: python unicode utf-8 unicode-escapes


【解决方案1】:

您不能明确地检测并替换字符串文字中的所有\ooo 转义序列,因为在您的第一行代码运行之前,这些转义序列已不可挽回地替换为其对应的字符值。就 Python 而言,"foo\041""foo!" 100% 相同,无法确定前一个对象是用转义序列定义的,而后者不是。

如果您对输入数据的形式有一定的灵活性,那么您仍然可以做您想做的事情。例如,如果您被允许使用原始字符串而不是常规字符串,则r"Hello\035" 在运行前不会被解释为“你好,后跟一个哈希标签”。它将被解释为“你好,后跟反斜杠,后跟 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() 获取输入字符串,此方法也适用,因为用户在该提示中键入的反斜杠不会被解释为转义序列。如果您执行print(replace_decimal_escapes(input())) 并且用户键入“Hello\035”,则输出将根据需要为“Hello#”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-25
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2021-10-28
    • 2013-01-03
    相关资源
    最近更新 更多