【问题标题】:Python: How can I replace full-width characters with half-width characters?Python:如何用半角字符替换全角字符?
【发布时间】:2010-03-11 02:42:08
【问题描述】:

如果这是 PHP,我可能会这样做:

function no_more_half_widths($string){
  $foo = array('1','2','3','4','5','6','7','8','9','10')
  $bar = array('1','2','3','4','5','6','7','8','9','10')
  return str_replace($foo, $bar, $string)
}

我在 python 中尝试了 .translate 函数,它表明数组的大小不同。我认为这是因为单个字符是用 utf-8 编码的。有什么建议么?

【问题讨论】:

    标签: python unicode translation


    【解决方案1】:

    内置的unicodedata模块可以做到:

    >>> import unicodedata
    >>> foo = u'1234567890'
    >>> unicodedata.normalize('NFKC', foo)
    u'1234567890'
    

    “NFKC”代表“Normalization FormKC[兼容性分解,后跟规范组合]”,将全角字符替换为半角字符,即Unicode equivalent

    请注意,它还会同时规范各种其他事物,例如单独的重音符号和罗马数字符号。

    【讨论】:

    • 这非常漂亮,但有副作用(正如你所注意到的),而且不灵活:它只有一种方式(全角到半角)。不过,如果这是可以接受的,那就太好了!
    【解决方案2】:

    在 Python3 中,可以使用下面的 sn-p。它在所有 ASCII 字符和相应的全角字符之间建立一个映射。最重要的是,这不需要您对容易出错的 ascii 序列进行硬编码。

     FULL2HALF = dict((i + 0xFEE0, i) for i in range(0x21, 0x7F))
     FULL2HALF[0x3000] = 0x20
          
     def halfen(s):
         '''
         Convert full-width characters to ASCII counterpart
         '''
         return str(s).translate(FULL2HALF)
    

    另外,同样的逻辑,你可以将半角字符转换为全角字符,代码如下:

     HALF2FULL = dict((i, i + 0xFEE0) for i in range(0x21, 0x7F))
     HALF2FULL[0x20] = 0x3000
          
     def fullen(s):
         '''
         Convert all ASCII characters to the full-width counterpart.
         '''
         return str(s).translate(HALF2FULL)
    

    注意:这两个sn-ps只考虑ASCII字符,不转换任何日韩全角字符。

    为了完整起见,来自wikipedia

    Range U+FF01–FF5E 将 ASCII 21 到 7E 的字符再现为 全角形式,即 CJK 中使用的固定宽度形式 计算。这对于在 CJK 中排版拉丁字符很有用 环境。 U+FF00 不对应全角 ASCII 20 (空格字符),因为该角色已由U+3000 完成 “表意空间。”

    Range U+FF65–FFDC 编码片假名和韩文的半角形式 字符。

    范围U+FFE0–FFEE 包括全角和半角符号。

    可以在gist/jcayzac找到python2解决方案。

    【讨论】:

    • 感谢您的完美解决方案!它真的对我帮助很大。
    【解决方案3】:

    在 Python 3 中,最简洁的方法是使用 str.translatestr.maketrans

    FULLWIDTH_TO_HALFWIDTH = str.maketrans('1234567890',
                                           '1234567890')
    def fullwidth_to_halfwidth(s):
        return s.translate(FULLWIDTH_TO_HALFWIDTH)
    

    在 Python 2 中,str.maketrans 改为 string.maketrans,并且不适用于 Unicode 字符,因此您需要制作一个字典,正如上面 Josh Lee 所述。

    【讨论】:

      【解决方案4】:

      正则表达式方法

      >>> import re
      >>> re.sub(u"[\uff10-\uff19]",lambda x:chr(ord(x.group(0))-0xfee0),u"456")
      u'456'
      

      【讨论】:

        【解决方案5】:

        我不认为有一个内置函数可以一次完成多个替换,所以你必须自己做。

        一种方法:

        >>> src = (u'1',u'2',u'3',u'4',u'5',u'6',u'7',u'8',u'9',u'10')
        >>> dst = ('1','2','3','4','5','6','7','8','9','0')
        >>> string = u'a123'
        >>> for i, j in zip(src, dst):
        ...     string = string.replace(i, j)
        ... 
        >>> string
        u'a123'
        

        或者使用字典:

        >>> trans = {u'1': '1', u'2': '2', u'3': '3', u'4': '4', u'5': '5', u'6': '6', u'7': '7', u'8': '8', u'9': '9', u'0': '0'}
        >>> string = u'a123'
        >>> for i, j in trans.iteritems():
        ...     string = string.replace(i, j)
        ...     
        >>> string
        u'a123'
        

        或者最后,使用正则表达式(这实际上可能是最快的):

        >>> import re
        >>> trans = {u'1': '1', u'2': '2', u'3': '3', u'4': '4', u'5': '5', u'6': '6', u'7': '7', u'8': '8', u'9': '9', u'0': '0'}
        >>> lookup = re.compile(u'|'.join(trans.keys()), re.UNICODE)
        >>> string = u'a123'
        >>> lookup.sub(lambda x: trans[x.group()], string)
        u'a123'
        

        【讨论】:

          【解决方案6】:

          使用unicode.translate 方法:

          >>> table = dict(zip(map(ord,u'0123456789'),map(ord,u'0123456789')))
          >>> print u'123'.translate(table)
          123
          

          它需要将代码点映射为数字,而不是字符。此外,使用 u'unicode literals' 会使值未编码。

          【讨论】:

          • 不错!我不知道unicode 有一个与纯str 不同的translate() 方法,尽管回想起来它很有意义。
          猜你喜欢
          • 2019-01-01
          • 2012-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-30
          • 1970-01-01
          • 1970-01-01
          • 2017-05-24
          相关资源
          最近更新 更多