Python实现全角与半角相互转换

全角与半角转换在处理汉语语料中会经常出现,这里分别说明汉字、数字、字母的unicode编码范围。以及全角与半角的转换方法。最后给出wiki上全角和半角的编码对照表。这里Python需要用Python3版本。

汉字的判断

汉字的unicode编码范围 u4e00 到 u9fa5。

def is_chinese(uchar):
    """判断一个unicode是否是汉字"""
    if uchar >= u'\u4e00' and uchar<=u'\u9fa5':
        return True
    else:
        return False

数字0-9的判断

数字的unicode编码范围根据全角和半角,有两个不同区域,半角数字 u0030 到 u0039,全角数字 uff10 到 uff19。

def is_number(uchar):
    """判断一个unicode是否是半角数字"""
    if uchar >= u'\u0030' and uchar<=u'\u0039':
        return True
    else:
        return False
    
def is_Qnumber(uchar):
    """判断一个unicode是否是全角数字"""
    if uchar >= u'\uff10' and uchar <= u'\uff19':
        return True
    else:
        return False

大小写字母判断

字母的unicode编码根据字母大小写,以及全角和半角共有四个区域。
半角大写字母:u0041 - u005a ,半角小写字母:u0061 - u007a ;
全角大写字母:uff21 - uff3a , 全角小写字母:uff41 - uff5a 。

def is_alphabet(uchar):
    """判断一个unicode是否是半角英文字母"""
    if (uchar >= u'\u0041' and uchar <= u'\u005a') or (uchar >= u'\u0061' and uchar <= u'\u007a'):
        return True
    else:
        return False

def is_Qalphabet(uchar):
    """判断一个unicode是否是全角英文字母"""
    if (uchar >= u'\uff21' and uchar <= u'\uff3a') or (uchar >= u'\uff41' and uchar <= u'\uff5a'):
        return True
    else:
        return False

非汉字和数字字母的判断

判断除汉字、数字0-9、字母之外的字符。

def is_other(uchar):
    """判断是否非汉字,数字和英文字符"""
    if not (is_chinese(uchar) or is_number(uchar) or is_alphabet(uchar)):
        return True
    else:
        return False

全角和半角的转换

全角半角转换需要用到上面的数字、字母等判断。

  1. 所有半角转全角,不是半角范围直接返回,空格半角特殊单独处理,其它半角和全角对应公式:半角 = 全角 - 0xfee0
def B2Q(uchar):
    """单个字符 半角转全角"""
    inside_code = ord(uchar)
    if inside_code < 0x0020 or inside_code > 0x7e: # 不是半角字符就返回原来的字符
        return uchar 
    if inside_code == 0x0020: # 除了空格其他的全角半角的公式为: 半角 = 全角 - 0xfee0
        inside_code = 0x3000
    else:
        inside_code += 0xfee0
    return chr(inside_code)
  1. 所有全角转半角,和前面正好相反,公式对应:全角 = 半角 + 0xfee0
def Q2B(uchar):
    """单个字符 全角转半角"""
    inside_code = ord(uchar)
    if inside_code == 0x3000:
        inside_code = 0x0020
    else:
        inside_code -= 0xfee0
    if inside_code < 0x0020 or inside_code > 0x7e: #转完之后不是半角字符返回原来的字符
        return uchar
    return chr(inside_code)
  1. 把整个字符串全角转半角,也可以只转部分如数字和字母
def stringQ2B(ustring):
    """把字符串全角转半角"""
    return "".join([Q2B(uchar) for uchar in ustring])

def stringpartQ2B(ustring):
    """把字符串中数字和字母全角转半角"""
    return "".join([Q2B(uchar) if is_Qnumber(uchar) or is_Qalphabet(uchar) else uchar for uchar in ustring])

测试上面的全角半角转换。

text = "电影《2012》讲述了2012年12月21日的世界末日,主人公Jack以及世界各国人民挣扎求生的经历,灾难面前,尽现人间百态。"

print("text原文:", text, sep="\n", end="\n")
text1 = stringQ2B(text)
print("全角转半角:", text1, sep="\n", end="\n")
text2 = stringpartQ2B(text)
print("数字字母全角转半角:", text2, sep="\n", end="\n")

结果如下,只转数字字母与全部转是有区别的:
在这里插入图片描述

附全角和半角编码对应表

  1. ASCII内字符的全角和半角,包括数字0-9、大小写字母、标点符号等。
ASCII全角字符Unicode半角字符Unicode
0x20" "U+3000" "U+0020
0x21U+FF01!U+0021
0x22U+FF02"U+0022
0x23U+FF03#U+0023
0x24U+FF04$U+0024
0x25U+FF05%U+0025
0x26U+FF06&U+0026
0x27U+FF07U+0027
0x28U+FF08(U+0028
0x29U+FF09)U+0029
0x2AU+FF0A*U+002A
0x2BU+FF0B+U+002B
0x2CU+FF0C,U+002C
0x2DU+FF0D-U+002D
0x2EU+FF0E.U+002E
0x2FU+FF0F/U+002F
0x30U+FF100U+0030
0x31U+FF111U+0031
0x32U+FF122U+0032
0x33U+FF133U+0033
0x34U+FF144U+0034
0x35U+FF155U+0035
0x36U+FF166U+0036
0x37U+FF177U+0037
0x38U+FF188U+0038
0x39U+FF199U+0039
0x3AU+FF1A:U+003A
0x3BU+FF1B;U+003B
0x3CU+FF1C<U+003C
0x3DU+FF1D=U+003D
0x3EU+FF1E>U+003E
0x3FU+FF1F?U+003F
0x40U+FF20@U+0040
0x41U+FF21AU+0041
0x42U+FF22BU+0042
0x43U+FF23CU+0043
0x44U+FF24DU+0044
0x45U+FF25EU+0045
0x46U+FF26FU+0046
0x47U+FF27GU+0047
0x48U+FF28HU+0048
0x49U+FF29IU+0049
0x4AU+FF2AJU+004A
0x4BU+FF2BKU+004B
0x4CU+FF2CLU+004C
0x4DU+FF2DMU+004D
0x4EU+FF2ENU+004E
0x4FU+FF2FOU+004F
0x50U+FF30PU+0050
0x51U+FF31QU+0051
0x52U+FF32RU+0052
0x53U+FF33SU+0053
0x54U+FF34TU+0054
0x55U+FF35UU+0055
0x56U+FF36VU+0056
0x57U+FF37WU+0057
0x58U+FF38XU+0058
0x59U+FF39YU+0059
0x5AU+FF3AZU+005A
0x5BU+FF3B[U+005B
0x5CU+FF3C\U+005C
0x5DU+FF3D]U+005D
0x5EU+FF3E^U+005E
0x5F_U+FF3F_U+005F
0x60U+FF40`U+0060
0x61U+FF41aU+0061
0x62U+FF42bU+0062
0x63U+FF43cU+0063
0x64U+FF44dU+0064
0x65U+FF45eU+0065
0x66U+FF46fU+0066
0x67U+FF47gU+0067
0x68U+FF48hU+0068
0x69U+FF49iU+0069
0x6AU+FF4AjU+006A
0x6BU+FF4BkU+006B
0x6CU+FF4ClU+006C
0x6DU+FF4DmU+006D
0x6EU+FF4EnU+006E
0x6FU+FF4FoU+006F
0x70U+FF50pU+0070
0x71U+FF51qU+0071
0x72U+FF52rU+0072
0x73U+FF53sU+0073
0x74U+FF54tU+0074
0x75U+FF55uU+0075
0x76U+FF56vU+0076
0x77U+FF57wU+0077
0x78U+FF58xU+0078
0x79U+FF59yU+0079
0x7AU+FF5AzU+007A
0x7BU+FF5B{U+007B
0x7CU+FF5C|U+007C
0x7DU+FF5D}U+007D
0x7EU+FF5E~U+007E
  1. 其它特殊字符的全角和半角
半角字符Unicode全角字符Unicode
U+2985U+FF5F
U+2986U+FF60
¢U+00A2U+FFE0
£U+00A3U+FFE1
¬U+00ACU+FFE2
¯U+00AFU+FFE3
¦U+00A6U+FFE4
¥U+00A5U+FFE5
U+20A9U+FFE6
U+FFE8U+2502
U+FFE9U+2190
U+FFEAU+2191
U+FFEBU+2192
U+FFECU+2193
U+FFEDU+25A0
U+FFEEU+25CB

参考

[1]. https://zh.wikipedia.org/wiki/全形和半形
[2]. http://www.voidcn.com/article/p-njiniuhl-nu.html

posted @ 2019-05-20 23:00  黄然小悟  阅读(754)  评论(0编辑  收藏  举报