Python: 如何将全角字符替换为半角字符?
如果这是用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编码的。有什么建议吗?
6 个回答
3
正则表达式的方法
>>> import re
>>> re.sub(u"[\uff10-\uff19]",lambda x:chr(ord(x.group(0))-0xfee0),u"456")
u'456'
11
在Python3中,你可以使用下面的代码片段。它创建了一个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)
注意:这两个代码片段只考虑ASCII字符,并不转换任何日文或韩文的全角字符。
为了完整性,来自维基百科的说明:
范围
U+FF01–FF5E
将ASCII 21到7E的字符转换为全角形式,也就是在中日韩计算环境中使用的固定宽度形式。这对于在中日韩环境中排版拉丁字符非常有用。U+FF00
并不对应全角ASCII 20(空格字符),因为这个角色已经由U+3000
“表意空格”来承担。范围
U+FF65–FFDC
编码了片假名和韩文字符的半角形式。范围
U+FFE0–FFEE
包括全角和半角符号。
你可以在gist/jcayzac找到Python2的解决方案。
38
内置的 unicodedata
模块可以做到这一点:
>>> import unicodedata
>>> foo = u'1234567890'
>>> unicodedata.normalize('NFKC', foo)
u'1234567890'
这里的 “NFKC” 是指 “规范化形式 KC [兼容性分解,然后是规范组合]”,它的作用是把全角字符替换成半角字符,这两者在 Unicode中是等价的。
需要注意的是,它同时也会规范化其他各种东西,比如分开的重音符号和罗马数字符号。