下面這個小工具包含了判斷unicode是不是漢字、數字、英文或者其餘字符,全角符號轉半角符號,unicode字符串歸一化等工做。python
#!/usr/bin/env pythonapp
"""漢字處理的工具: 判斷unicode是不是漢字,數字,英文,或者其餘字符。 全角符號轉半角符號。"""ide
author="internetsweeper zhengbin0713@gmail.com" date="2007-08-04"函數
def is_chinese(uchar): """判斷一個unicode是不是漢字""" if uchar >= u'\u4e00' and uchar<=u'\u9fa5': return True else: return False工具
def is_number(uchar): """判斷一個unicode是不是數字""" if uchar >= u'\u0030' and uchar<=u'\u0039': return True else: return False編碼
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 Falsecode
def is_other(uchar): """判斷是否非漢字,數字和英文字符""" if not (is_chinese(uchar) or is_number(uchar) or is_alphabet(uchar)): return True else: return Falseorm
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 unichr(inside_code)對象
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 unichr(inside_code)內存
def stringQ2B(ustring): """把字符串全角轉半角""" return "".join([Q2B(uchar) for uchar in ustring])
def uniform(ustring): """格式化字符串,完成全角轉半角,大寫轉小寫的工做""" return stringQ2B(ustring).lower()
def string2List(ustring): """將ustring按照中文,字母,數字分開""" retList=[] utmp=[] for uchar in ustring: if is_other(uchar): if len(utmp)==0: continue else: retList.append("".join(utmp)) utmp=[] else: utmp.append(uchar) if len(utmp)!=0: retList.append("".join(utmp)) return retList
if name=="main": #test Q2B and B2Q for i in range(0x0020,0x007F): print Q2B(B2Q(unichr(i))),B2Q(unichr(i))
#test uniform ustring=u'中國 人名a高頻A' ustring=uniform(ustring) ret=string2List(ustring) print ret
以上轉自http://hi.baidu.com/fenghua1893/item/d1a71d5ac47ffdcfd3e10cd1
這個問題是作 MkIV 預處理程序時搞定的,就是把一個混合了中英文混合字串分離爲英文與中文的子字串,譬如,將 」個人 English 學的很差「 分離爲 「個人"、" English 」 與 "學的很差" 三個子字串。
中英文混合字串的統一編碼表示中英文混合字串處理最省力的辦法就是把它們的編碼都轉成 Unicode,讓一個漢字與一個英文字母的內存位寬都是相等的。這個工做用 Python 來作,比較合適,由於 Python 內碼採用的是 Unicode,而且爲了支持 Unicode 字串的操做,Python 作了一個 Unicode 內建模塊,把 string 對象的所有方法從新實現了一遍,另外提供了 Codecs 對象,解決各類編碼類型的字符串解碼與編碼問題。 譬以下面的 Python 代碼,可實現 UTF-8 編碼的中英文混合字串向 Unicode 編碼的轉換:# -- coding:utf-8 -- a = "個人 English 學的很差" print type(a),len (a), a b = unicode (a, "utf-8") print type(b), len (b), b字符串 a 是 utf-8 編碼,使用 python 的內建對象 unicode 可將其轉換爲 Unicode 編碼的字符串 b。上述代碼執行後的輸出結果以下所示,比較字串 a 與字串 b 的長度,顯然 len (b) 的輸出結果是合理的。<type 'str'> 27 個人 English 學的很差 <type 'unicode'> 15 個人 English 學的很差要注意的一個問題是 Unicode 雖然號稱是「統一碼」,不過也是存在着兩種形式,即: UCS-2:爲 16 位碼,具備 2^16 = 65536 個碼位; UCS-4:爲 32 位碼,目前的規定是其首字節的首位爲 0,所以具備 2^31 = 2147483648 個碼位,不過如今的只使用了 0x00000000 - 0x0010FFFF 之間的碼位,共 1114112 個。 使用Python sys 模塊提供的一個變量 maxunicode 的值能夠判斷當前 Python 所使用的 Unicode 類型是 UCS-2 的仍是 UCS-4 的。import sys print sys.maxunicode若 sys.maxunicode 的值爲 1114111,即爲 UCS-4;若爲 65535,則爲 UCS-2。
中英文混合字串的分離一旦中英文字串的編碼得到統一,那麼對它們進行分裂就是很簡單的事情了。首先要爲中文字串與英文字串分別準備一個收集器,使用兩個空的字串對象便可,譬如 zh_gather 與 en_gather;而後要準備一個列表對象,負責按分離次序存儲 zh_gather 與 en_gather 的值。下面這個 Python 函數接受一箇中英文混合的 Unicode 字串,並返回存儲中英文子字串的列表。def split_zh_en (zh_en_str):
zh_en_group = [] zh_gather = "" en_gather = "" zh_status = False for c in zh_en_str: if not zh_status and is_zh (c): zh_status = True if en_gather != "": zh_en_group.append ([mark["en"],en_gather]) en_gather = "" elif not is_zh (c) and zh_status: zh_status = False if zh_gather != "": zh_en_group.append ([mark["zh"], zh_gather]) if zh_status: zh_gather += c else: en_gather += c zh_gather = "" if en_gather != "": zh_en_group.append ([mark["en"],en_gather]) elif zh_gather != "": zh_en_group.append ([mark["zh"],zh_gather]) return zh_en_group上述代碼所實現的功能細節是:對中英文混合字串 zh_en_str 的遍歷過程當中進行逐字識別,若當前字符爲中文,則將其添加到 zh_gather 中;若當前字符爲英文,則將其添加到 en_gather 中。zh_status 表示中英文字符的切換狀態,當 zh_status 的值發生突變時,就將所收集的中文子字串或英文子字串添加到 zh_en_group 中去。
判斷字串 zh_en_str 中是否包含中文字符的條件語句中出現了一個 is_zh () 函數,它的實現以下:def is_zh (c): x = ord (c) # Punct & Radicals if x >= 0x2e80 and x <= 0x33ff: return True
# Fullwidth Latin Characters elif x >= 0xff00 and x <= 0xffef: return True # CJK Unified Ideographs & # CJK Unified Ideographs Extension A elif x >= 0x4e00 and x <= 0x9fbb: return True # CJK Compatibility Ideographs elif x >= 0xf900 and x <= 0xfad9: return True # CJK Unified Ideographs Extension B elif x >= 0x20000 and x <= 0x2a6d6: return True # CJK Compatibility Supplement elif x >= 0x2f800 and x <= 0x2fa1d: return True else: return False這段代碼來自 jjgod 寫的 XeTeX 預處理程序。
對於分離出來的中文子字串與英文子字串,爲了使用方便,在將它們存入 zh_en_group 列表時,我對它們分別作了標記,即 mark["zh"] 與 mark["en"]。mark 是一個 dict 對象,其定義以下:mark = {"en":1, "zh":2}若是要對 zh_en_group 中的英文字串或中文字串進行處理時,標記的意義在於快速斷定字串是中文的,仍是英文的,譬如:for str in zh_en_group: if str[0] = mark["en"]: do somthing else: do somthing