相关文章推荐
文雅的椅子  ·  sql ...·  1 年前    · 
酒量大的饭卡  ·  python - Pymodbus - ...·  1 年前    · 

对字符串变量中的单个八进制字符进行解码

0 人关注

一个字符串变量有时包括八进制字符,需要取消八进制。例如。 oct_var = "String\302\240with\302\240octals" oct_var 的值应该是 "String with octals" ,并带有非断裂空格。

Codecs 不支持八进制,我也没能用 encode() 找到一个有效的解决方案。这些字符串源自我控制之外的上游。

Python 3.9.8

编辑补充。 它不一定要有规模,也不一定要有超快的速度,所以也许这个想法从 here (#6)可以工作(还没有测试)。

def decode(encoded):
    for octc in (c for c in re.findall(r'\\(\d{3})', encoded)):
        encoded = encoded.replace(r'\%s' % octc, chr(int(octc, 8)))
    return encoded.decode('utf8')
    
4 个评论
这是否回答了你的问题? 转换UTF-8的八进制表示法
我也有和OP一样的问题 -- "我不能写b'\320...\271',因为我把八进制的值作为一个字符串对象动态地获取"。
从那里的一个链接(感谢)这看起来是一个解决方案。 stackoverflow.com/questions/4020539/... ,滚动到 "添加正则表达式来解决问题",并在下面。
鉴于 "字符串源自我控制之外的上游 "的信息,请参见最新答案。
python
string
variables
octal
calisprontix
calisprontix
发布于 2021-12-23
2 个回答
Pierre D
Pierre D
发布于 2021-12-23
已采纳
0 人赞同

你忘了指出, oct_var 应该以字节的形式给出。

>>> oct_var = b"String\302\240with\302\240octals"
>>> oct_var.decode()
'String\xa0with\xa0octals'
>>> print(oct_var.decode())
String with octals

注意:如果你的值已经是一个字符串(超出你的控制),你可以try to convert it to bytes:

>>> oct_str = "String\302\240with\302\240octals"  # as a string
>>> oct_var = bytes([ord(c) for c in oct_str])
# often equivalent to:
>>> oct_var = oct_str.encode('Latin1')

然后按上述方法进行。

注意,如果该字符串还包含超出ASCII的字符,(例如。与Latin1,重音字符如'é'),随后的.decode()将失败,因为在UTF-8中,这些字符被表示为多字节的字符(例如:'é'.encode() == b'\xc3\xa9',但'é'.encode('Latin1') == b'\xe9')。如果字符串包含超出Latin1的Unicode字符(例如'你好'),你将得到一个ValueErrorUnicodeEncodeError,这取决于你选择的两种转换方法)。

简而言之:不要带着昂贵的、沉重的、或者里面有人的东西飞行--这是黑客行为。至少,用try ... except (ValueError, UnicodeEncodeError, UnicodeDecodeError)包围你的代码并相应地处理这些异常。

这触及了一个重要的问题。 这些代码( \302\240 )是UTF-8对非断裂空间U+0040的表示。 如果这些八进制代码出现在Unicode字符串中,你就有问题了。 你真的需要把它作为一个字节字符串,在这种情况下,转换是很容易的,正如皮埃尔所正确表明的那样。
我们被困于--不会突然消失但不可靠的解决方案,以及--对Python开发者来说足够稳定的东西[1],但可以在任何时候不经通知就消失。 codecs.escape_decode 可以放在一个 try ... except 里面,当它被调用时,会发出某种通知,但Python中不再提供。也许到那时我们会有一个替换代码。 [1] "......当它在 pickle 模块中使用时,我们不能直接删除它,而且没有理由改变它,因为它的作用非常好..."
calisprontix
calisprontix
发布于 2021-12-23
0 人赞同

把你的想法和指针放在一起,并与使用的风险 undocumented function [*] , i.e, codecs.escape_decode , this line works:

value = (codecs.escape_decode(bytes(oct_var, "latin-1"))[0].decode("utf-8"))

[*] "内部功能意味着:你可以在你的风险上使用它,但 功能可以改变,甚至可以删除 在任何Python版本中"。

codecs.escape_decode 的解释。

https://stackoverflow.com/a/37059682/5309571