背景:
在做日文文本的处理时候,统一半全角字符。
分析:
说明:
全角字符unicode编码从65281~65374 (十六进制 0xFF01 ~ 0xFF5E)
半角字符unicode编码从33~126 (十六进制 0x21~ 0x7E)
特例:
空格比较特殊,全角为 12288(0x3000),半角为 32(0x20)
除空格外,全角/半角按unicode编码排序在顺序上是对应的(半角 + 0xfee0= 全角),所以可以直接通过用+-法来处理非空格数据,对空格单独处理。
代码:
# -*- coding: utf-8 -*-
__author__ = 'jason'
'''
功能:
全角转为半角
注:
1. 中文文字永远是全角,只有英文字母、数字键、符号键才有全角半角的概念,一个字母或数字占一个汉字的位置叫全角,占半个汉字的位置叫半角。
2. 引号在中英文、全半角情况下是不同的
chr()函数用一个范围在range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
unichr()跟它一样,只不过返回的是Unicode字符。
ord()函数是chr()函数(对于8位的ASCII字符串)或unichr()函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的ASCII数值,或者Unicode数值。
0x3000: u' ', 0x2212: u'-'
'''
def FullToHalf(mystring):
n = []
s = mystring.decode('utf-8')
for char in s:
num = ord(char)
if num == 0x3000:
num = 32
elif 0xFF01 <= num <= 0xFF5E:
num -= 0xfee0
num = unichr(num)
n.append(num)
return ''.join(n)
teststring = "abc-+--ABC123你好世界,。!、"
resu = FullToHalf(teststring)
print "原始字符串:\n%s" % (teststring)
resu = resu.encode('utf8')
print "转为半角后的字符串:\n%s" % resu
#对于减号或者破折号的处理
a_half = u'-'#半角减号---−
print "半角减号unicode值=%#x" % (ord(a_half))
a_full = u"-"#全角减号--−
print "全角减号unicode值=%#x" % ord(a_full)
print "全角减号:\n%s" % unichr(ord(a_full)).encode('utf-8')#全角减号
print "半角减号1:\n%s" % unichr(ord(a_half)).encode('utf-8')#半角减号,0x2d
print "半角减号2:\n%s" % unichr(0x2212).encode('utf-8')#半角减号,0x2212,其实这个符号并不在半角范围内
chazhia_b = ord(a_full) - 0x2212
new_ban_jiao = ord(a_full)-0xfee0#ascii=45,其实是减号/破折号
print "减号全角和半角差值=%#x, 通过将全角减去0xfee0获取的半角:%s" % (chazhia_b, unichr(new_ban_jiao).encode('utf-8'))
#其实仔细观看,通过减法获得到的减号和原生半角减号是不同的。
quan_a = u'a'
ban_a = u'a'
diff_a = ord(quan_a)-ord(ban_a)
print "quan_a=%#x,ban_b=%#x,diff_a=%#x" % (ord(quan_a),ord(ban_a),diff_a)
chazhi1 = ord(quan_a)-0xfee0
print "new_ban_a=%s" % (unichr(ord(quan_a)-diff_a))