如何在字节字符串中的表达式'\xb'后提取数值

2024-09-27 21:25:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从RS-232端口传输的字节字符串中提取数值。举个例子:

b'S\xa0S\xa0\xa0\xa0\xa0\xa0\xa0\xb23.6\xb7\xa0\xe7\x8d\n'

如果我尝试将字节字符串解码为“utf-8”,我将收到以下输出:

x = b'S\xa0S\xa0\xa0\xa0\xa0\xa0\xa0\xb23.6\xb7\xa0\xe7\x8d\n'
x.decode('utf-8', errors='ignore')

>>> 'SS3.6\n'

理想情况下我想要的是23.67,这是在每个\xb模式之后观察到的。如何从这个字节字符串中提取23.67?你知道吗


Tags: 端口字符串字节解码utf例子数值xa0
3条回答

正如在https://stackoverflow.com/a/59416410/3319460中提到的,您的输入实际上并不代表您所寻求的输出。当然,为了满足您的需求,我们可以对输入设置语义,以便

  • 允许数字或'.'符号,跳过其他符号
  • 如果字节是非ASCII字符,例如前四个字节是否为0xB。如果是这样的话,那么我们将只取字节的ASCII部分(b & 0b01111111

用Python很容易做到这一点。你知道吗

def _filter(char):
    return char & 0xF0 == 0xB0 or chr(char) == "." or 48 <= char <= 58


def filter_xbchars(value: bytes) -> str:
    return "".join(chr(ch & 0b01111111) for ch in value if _filter(ch))


import pytest


@pytest.mark.parametrize(
    "value, expected",
    [(b"S\xa0S\xa0\xa0\xa0\xa0\xa0\xa0\xb23.6\xb7\xa0\xe7\x8d\n", "23.67")],
)
def test_simple(value, expected):
    assert filter_xbchars(value) == expected

请注意尽管上面的代码满足要求但这是一个描述不好的任务的例子,因此是一个非常荒谬的解决方案。代码按照您的要求解决了任务,但我们应该首先重新考虑它是否有意义。我建议您检查您要测试的数据和数据的含义(协议)。你知道吗

祝你好运:)

请注意,\xHH是表示十六进制值HH的转义码,因此您的字符串'\xb23.6\xb7'不包含"23.67",但是rater "(0xB2)3.6(0xB7)",这些值不能使用正则表达式提取,因为它首先不在字符串中。你知道吗

'\xb23.6\xb7'不是一个有效的UTF-8序列,在Latin-1 extended ASCII中它代表"²3.6·";许多0xA0值的存在表明是拉丁-1编码,因为它在该编码中代表一个不间断的空格(一个相当常见的字符),而在UTF-8中它不编码有意义的序列。你知道吗

如果您只想从该字节字符串中获取23.67,请尝试以下操作:

a = b'S\xa0S\xa0\xa0\xa0\xa0\xa0\xa0\xb23.6\xb7\xa0\xe7\x8d\n'
b = repr(a)[2:-1]
c = b.split("\\")
d = ''
e = []
for i in c:
    if "xb" in i:
        e.append(i[2:])
d = "".join(e)
print(d)

相关问题 更多 >

    热门问题