【问题标题】:How to detect double-byte numbers如何检测双字节数字
【发布时间】:2014-11-06 05:10:04
【问题描述】:

我必须检查以双字节字符编码的日语字符串(这些文件自然不是 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

任何建议将不胜感激!

【问题讨论】:

  • 将字符串转换为 unicode,使用 unicode 正则表达式搜索,对字符串执行任何操作,转换回 shift-jis...
  • 就像@isedev 已经说过的那样,确保您始终在 Python 中使用 unicode(而不是 UTF8/16)。然后,您可以使用 unicodedata 模块为您提供有关字符的信息,例如:unicodedata.numeric(u'1') => 1.0unicodedata.name(u'1') => 'FULLWIDTH DIGIT ONE'unicodedata.digit(u'1') => 1
  • 我之前尝试过,但收效甚微。所有 Shift-JIS 都可以转换为 Unicode,但反之则不行。我会再试一次。
  • @Tensigh 我认为您混淆了 Unicode 和 UTF 编码。你不能将 Unicode 从 Python(或任何语言)输出到文件、网络、STDOUT 等。你只能输出一个字节串,它需要用像 UTF-8 这样的编码进行编码。
  • @LukasGraf,谢谢,这是一个很好的解释。

标签: python regex character-encoding python-2.x digits


【解决方案1】:

首先,cmets 是正确的:为了您的理智,您应该只在 Python 代码中使用 unicode,从进来的 Shift-JIS 解码,然后再编码回 Shift-JIS(如果是这样的话)你需要输出:

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

请参阅:Convert text at the border

既然你做对了 re: 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 标志,请参阅 here

【讨论】:

  • 哦,shift_jis 是一个编码!出于某种原因,我假设它是一个 JavaScript 框架。现在我觉得自己很愚蠢 :) 不管怎样,答案都很好!
【解决方案2】:

我在面对日文的两字节字符时遇到了类似的问题,我发现处理这些字符的一种相对简单的方法是使用简单的 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) 范围添加相同的内容。

【讨论】:

    猜你喜欢
    • 2013-04-01
    • 2011-02-14
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 2013-06-09
    • 2015-03-18
    相关资源
    最近更新 更多