如何检测双字节数字

2 投票
2 回答
3866 浏览
提问于 2025-04-21 06:00

我需要检查一些用双字节字符编码的日文字符串(这些文件不是用Unicode编码的,我必须保持它们在Shift-JIS格式下)。很多字符串里包含的数字也是双字节字符,比如(123456789),而不是标准的单字节数字(0-9)。所以,通常用来查找数字的方法就不管用了(比如在正则表达式中用[0-9]或者\d)。

我找到的唯一可行的方法是创建一个元组,然后在字符串中遍历这个元组来寻找匹配,但有没有更有效的方法呢?

这是我在搜索双字节数字时得到的输出示例:

>>> s = "234"  # "2" is a double-byte integer
>>> if u"2" in s:
      print "y"

>>> if u"2" in s:
      print "y"

    y
>>> print s[0]

>>> print s[:2]
    2
>>> print s[:3]
    23

任何建议都非常感谢!

2 个回答

0

我在处理日本的双字节字符时遇到过类似的问题。我发现一个相对简单的方法是使用简单的Unicode数字来转换这些字符(至少在处理它们的时候,如果你想保持文档原样的话)。

ord("2")

这个方法会返回

65298

这个结果比单字节字符2多了65248个点。所以,如果要转换回去,可以用:

def convert_two_byte_numbers(character: str):
    if ord(character) in range(65296, 65306):
        return chr(ord(character) - 65248)
    else: 
        return character

如果你和我一样,也需要转换双字节字母,可以对范围(65313, 65339)(65345, 65371)做同样的处理。

4

首先,评论说得对:为了你的心理健康,你在Python代码中应该只使用unicode。也就是说,当你接收到Shift-JIS编码的数据时,要先解码成unicode,如果需要输出的话,再编码回Shift-JIS。

text = incoming_bytes.decode("shift_jis")
# ... do stuff ...
outgoing_bytes = text.encode("shift_jis")

详情请见:在边界转换文本

现在你已经正确处理unicode和编码的字节串了,使用正则表达式可以很简单地获取“任何数字”或“任何双宽数字”:

>>> import re
>>> s = u"234"
>>> digit = re.compile(r"\d", re.U)
>>> for d in re.findall(digit, s):
...     print d,
... 
2 3 4
>>> wdigit = re.compile(u"[0-9]+")
>>> for wd in re.findall(wdigit, s):
...     print wd,
... 
2

如果你对re.U这个标志不太熟悉,可以在这里找到相关文档。

撰写回答