全角与半角转换在处理汉语语料中会经常出现,这里分别说明汉字、数字、字母的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
全角和半角的转换
全角半角转换需要用到上面的数字、字母等判断。
- 所有半角转全角,不是半角范围直接返回,空格半角特殊单独处理,其它半角和全角对应公式:半角 = 全角 - 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)
- 所有全角转半角,和前面正好相反,公式对应:全角 = 半角 + 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)
- 把整个字符串全角转半角,也可以只转部分如数字和字母
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")
结果如下,只转数字字母与全部转是有区别的:

全角半角转换结果
附全角和半角编码对应表
- ASCII内字符的全角和半角,包括数字0-9、大小写字母、标点符号等。
| ASCII | 全角字符 | Unicode | 半角字符 | Unicode | 
|---|---|---|---|---|
| 0x20 | " " | U+3000 | " " | U+0020 | 
| 0x21 | ! | U+FF01 | ! | U+0021 | 
| 0x22 | " | U+FF02 | " | U+0022 | 
| 0x23 | # | U+FF03 | # | U+0023 | 
| 0x24 | $ | U+FF04 | $ | U+0024 | 
| 0x25 | % | U+FF05 | % | U+0025 | 
| 0x26 | & | U+FF06 | & | U+0026 | 
| 0x27 | ' | U+FF07 | ' | U+0027 | 
| 0x28 | ( | U+FF08 | ( | U+0028 | 
| 0x29 | ) | U+FF09 | ) | U+0029 | 
| 0x2A | * | U+FF0A | * | U+002A | 
| 0x2B | + | U+FF0B | + | U+002B | 
| 0x2C | , | U+FF0C | , | U+002C | 
| 0x2D | - | U+FF0D | - | U+002D | 
| 0x2E | . | U+FF0E | . | U+002E | 
| 0x2F | / | U+FF0F | / | U+002F | 
| 0x30 | 0 | U+FF10 | 0 | U+0030 | 
| 0x31 | 1 | U+FF11 | 1 | U+0031 | 
| 0x32 | 2 | U+FF12 | 2 | U+0032 | 
| 0x33 | 3 | U+FF13 | 3 | U+0033 | 
| 0x34 | 4 | U+FF14 | 4 | U+0034 | 
| 0x35 | 5 | U+FF15 | 5 | U+0035 | 
| 0x36 | 6 | U+FF16 | 6 | U+0036 | 
| 0x37 | 7 | U+FF17 | 7 | U+0037 | 
| 0x38 | 8 | U+FF18 | 8 | U+0038 | 
| 0x39 | 9 | U+FF19 | 9 | U+0039 | 
| 0x3A | : | U+FF1A | : | U+003A | 
| 0x3B | ; | U+FF1B | ; | U+003B | 
| 0x3C | < | U+FF1C | < | U+003C | 
| 0x3D | = | U+FF1D | = | U+003D | 
| 0x3E | > | U+FF1E | > | U+003E | 
| 0x3F | ? | U+FF1F | ? | U+003F | 
| 0x40 | @ | U+FF20 | @ | U+0040 | 
| 0x41 | A | U+FF21 | A | U+0041 | 
| 0x42 | B | U+FF22 | B | U+0042 | 
| 0x43 | C | U+FF23 | C | U+0043 | 
| 0x44 | D | U+FF24 | D | U+0044 | 
| 0x45 | E | U+FF25 | E | U+0045 | 
| 0x46 | F | U+FF26 | F | U+0046 | 
| 0x47 | G | U+FF27 | G | U+0047 | 
| 0x48 | H | U+FF28 | H | U+0048 | 
| 0x49 | I | U+FF29 | I | U+0049 | 
| 0x4A | J | U+FF2A | J | U+004A | 
| 0x4B | K | U+FF2B | K | U+004B | 
| 0x4C | L | U+FF2C | L | U+004C | 
| 0x4D | M | U+FF2D | M | U+004D | 
| 0x4E | N | U+FF2E | N | U+004E | 
| 0x4F | O | U+FF2F | O | U+004F | 
| 0x50 | P | U+FF30 | P | U+0050 | 
| 0x51 | Q | U+FF31 | Q | U+0051 | 
| 0x52 | R | U+FF32 | R | U+0052 | 
| 0x53 | S | U+FF33 | S | U+0053 | 
| 0x54 | T | U+FF34 | T | U+0054 | 
| 0x55 | U | U+FF35 | U | U+0055 | 
| 0x56 | V | U+FF36 | V | U+0056 | 
| 0x57 | W | U+FF37 | W | U+0057 | 
| 0x58 | X | U+FF38 | X | U+0058 | 
| 0x59 | Y | U+FF39 | Y | U+0059 | 
| 0x5A | Z | U+FF3A | Z | U+005A | 
| 0x5B | [ | U+FF3B | [ | U+005B | 
| 0x5C | \ | U+FF3C | \ | U+005C | 
| 0x5D | ] | U+FF3D | ] | U+005D | 
| 0x5E | ^ | U+FF3E | ^ | U+005E | 
| 0x5F | _ | U+FF3F | _ | U+005F | 
| 0x60 | ` | U+FF40 | ` | U+0060 | 
| 0x61 | a | U+FF41 | a | U+0061 | 
| 0x62 | b | U+FF42 | b | U+0062 | 
| 0x63 | c | U+FF43 | c | U+0063 | 
| 0x64 | d | U+FF44 | d | U+0064 | 
| 0x65 | e | U+FF45 | e | U+0065 | 
| 0x66 | f | U+FF46 | f | U+0066 | 
| 0x67 | g | U+FF47 | g | U+0067 | 
| 0x68 | h | U+FF48 | h | U+0068 | 
| 0x69 | i | U+FF49 | i | U+0069 | 
| 0x6A | j | U+FF4A | j | U+006A | 
| 0x6B | k | U+FF4B | k | U+006B | 
| 0x6C | l | U+FF4C | l | U+006C | 
| 0x6D | m | U+FF4D | m | U+006D | 
| 0x6E | n | U+FF4E | n | U+006E | 
| 0x6F | o | U+FF4F | o | U+006F | 
| 0x70 | p | U+FF50 | p | U+0070 | 
| 0x71 | q | U+FF51 | q | U+0071 | 
| 0x72 | r | U+FF52 | r | U+0072 | 
| 0x73 | s | U+FF53 | s | U+0073 | 
| 0x74 | t | U+FF54 | t | U+0074 | 
| 0x75 | u | U+FF55 | u | U+0075 | 
| 0x76 | v | U+FF56 | v | U+0076 | 
| 0x77 | w | U+FF57 | w | U+0077 | 
| 0x78 | x | U+FF58 | x | U+0078 | 
| 0x79 | y | U+FF59 | y | U+0079 | 
| 0x7A | z | U+FF5A | z | U+007A | 
| 0x7B | { | U+FF5B | { | U+007B | 
| 0x7C | | | U+FF5C | | | U+007C | 
| 0x7D | } | U+FF5D | } | U+007D | 
| 0x7E | ~ | U+FF5E | ~ | U+007E | 
- 其它特殊字符的全角和半角
| 半角字符 | Unicode | 全角字符 | Unicode | 
|---|---|---|---|
| ⦅ | U+2985 | ⦅ | U+FF5F | 
| ⦆ | U+2986 | ⦆ | U+FF60 | 
| ¢ | U+00A2 | ¢ | U+FFE0 | 
| £ | U+00A3 | £ | U+FFE1 | 
| ¬ | U+00AC | ¬ | U+FFE2 | 
| ¯ | U+00AF |  ̄ | U+FFE3 | 
| ¦ | U+00A6 | ¦ | U+FFE4 | 
| ¥ | U+00A5 | ¥ | U+FFE5 | 
| ₩ | U+20A9 | ₩ | U+FFE6 | 
| │ | U+FFE8 | │ | U+2502 | 
| ← | U+FFE9 | ← | U+2190 | 
| ↑ | U+FFEA | ↑ | U+2191 | 
| → | U+FFEB | → | U+2192 | 
| ↓ | U+FFEC | ↓ | U+2193 | 
| ■ | U+FFED | ■ | U+25A0 | 
| ○ | U+FFEE | ○ | U+25CB | 
参考
[1]. https://zh.wikipedia.org/wiki/%E5%85%A8%E5%BD%A2%E5%92%8C%E5%8D%8A%E5%BD%A2
[2]. http://www.voidcn.com/article/p-njiniuhl-nu.html