天天看點

Python正規表達式比對中文

從字元串的角度來說,中文不如英文整齊、規範,這是不可避免的現實。本文結合網上資料以及個人經驗,以 python 語言為例,稍作總結。歡迎補充或挑錯。 

通常我們可以使用 repr()函數檢視字串的原始格式。這對于寫正規表達式有所幫助。 

    python 的 re子產品有兩個相似的函數:re.match(), re.search 。

    兩個函數的比對過程完全一緻,隻是起點不同。

    match隻從字串的開始位置進行比對,如果失敗,它就此放棄;

    而search則會锲而不舍地完全周遊整個字串中所有可能的位置,直到成功地找到一個比對,或者搜尋完字串,以失敗告終。

    如果你了解match的特性(在某些情況下比較快),大可以自由用它;如果不太清楚,search通常是你需要的那個函數。

    從一堆文本中,找出所有可能的比對,以清單的形式傳回,這種情況用findall()這個函數。例子見後面的代碼。 

    unicode下,漢字的格式如\uxxxx,隻要找到對應的字元集的範圍,就能比對相應的字串,友善從多語言文本中挑出所需要的某種語言的文本。不過,對于像日文這樣的粘着語,既有中文字元,又有平假名片假名,或許結果會有所偏差。 

兩種字元類可以并列在一起使用,例如,平假名、片假名、中文的放在一起,u"[\u4e00-\u9fa5\u3040-\u309f\u30a0-\u30ff]+",來自定義所需要比對的文本。 

比對中文時,正規表達式和目标字串的格式必須相同。這一點至關重要。或者都用預設的utf8,此時你不用額外做什麼;如果是unicode,就需要在正則式之前加上u""格式。 

可以這樣定義unicode字元串:string=u"我愛正規表達式"。如果字串不是unicode的,可以使用unicode()函數轉換之。如果你知道源字串的編碼,可以使用newstr=unicode(oldstring, original_coding_name)的方式轉換,

例如 linux 下常用unicode(string, "utf8"),windows 下或許會用cp936吧

Python正規表達式比對中文

# -*- coding: utf-8 -*-   

import sys  

import re  

reload(sys)  

sys.setdefaultencoding('utf8')  

s=""" 

            en: regular expression is a powerful tool for manipulating text.  

            zh: 漢語是世界上最優美的語言,正規表達式是一個很有用的工具 

            jp: 正規表現は非常に役に立つツールテキストを操作することです。  

            jp-char: あアいイうウえエおオ  

            kr:정규 표현식은 매우 유용한 도구 텍스트를 조작하는 것입니다.  

            """  

print "原始utf8字元"  

#utf8  

print "--------"  

print repr(s)  

print "--------\n"  

#非ansi  

re_words=re.compile(r"[\x80-\xff]+")  

m =  re_words.search(s,0)  

print "非ansi字元"  

print m  

print m.group()  

#unicode  

s = unicode(s)  

print "原始unicode字元"  

#unicode chinese  

re_words = re.compile(u"[\u4e00-\u9fa5]+")  

print "unicode 中文"  

res = re.findall(re_words, s)       # 查詢出所有的比對字元串  

if res:  

    print "there are %d parts:\n"% len(res)   

    for r in res:   

        print "\t",r   

        print   

#unicode korean  

re_words=re.compile(u"[\uac00-\ud7ff]+")  

print "unicode 韓文"  

#unicode japanese katakana  

re_words=re.compile(u"[\u30a0-\u30ff]+")  

print "unicode 日文 片假名"  

#unicode japanese hiragana  

re_words=re.compile(u"[\u3040-\u309f]+")  

print "unicode 日文 平假名"  

#unicode cjk punctuation  

re_words=re.compile(u"[\u3000-\u303f\ufb00-\ufffd]+")  

print "unicode 标點符号"  

下面是google出現的幾種主要非英文字元集的編碼範圍

主要非英文語系字元範圍

範圍

編碼

說明

2e80~33ffh

中日韓符号區

收容康熙字典部首、中日韓輔助部首、注音符号、日本假名、韓文音符,中日韓的符号、标點、帶圈或帶括符文數字、月份,以及日本的假名組合、機關、年号、月份、日期、時間等。

3400~4dffh

中日韓認同文字擴充a區

中日韓認同表意文字擴充a區,總計收容6,582個中日韓漢字。

4e00~9fffh

中日韓認同表意文字區

中日韓認同表意文字區,總計收容20,902個中日韓漢字。

a000~a4ffh

彜族文字區

收容中國南方彜族文字和字根

ac00~d7ffh

韓文拼音組合字區

收容以韓文音符拼成的文字

f900~faffh

中日韓相容表意文字區

總計收容302個中日韓漢字

fb00~fffdh

文字表現形式區

收容組合拉丁文字、希伯來文、阿拉伯文、中日韓直式标點、小符号、半角符号、全角符号等。

比如需要比對所有中日韓非符号字元,那麼正規表達式應該是^[\u3400-\u9fff]+$

理論上沒錯, 可是我到msn.co.ko随便複制了個韓文下來, 發現根本不對, 詭異

再到msn.co.jp複制了個’お’, 也不得行..

然後把範圍擴大到^[\u2e80-\u9fff]+$, 這樣倒是都通過了, 這個應該就是比對中日韓文字的正規表達式了, 包括我們臺灣省還在盲目使用的繁體中文

而關于中文的正規表達式, 應該是^[\u4e00-\u9fff]+$, 和論壇裡常被人提起的^[\u4e00-\u9fa5]+$很接近

需要注意的是論壇裡說的^[\u4e00-\u9fa5]+$這是專門用于比對簡體中文的正規表達式, 實際上繁體字也在裡面, 我用測試器測試了下’中華人民共和國’, 也通過了, 當然, ^[\u4e00-\u9fff]+$也是一樣的結果。

    那麼我們很多時候如果要比對的内容如果既有中文也有英文,比如我們要比對一個可以由中文字母以及一些其他字元組成的标題,該怎麼寫呢,我麼接着看下面的代碼

Python正規表達式比對中文

#!coding:utf-8  

# 測試比對中文資訊  

def testrechinese( ):  

    source  =   u"        資料結構模版----單連結清單simplelinklist[帶頭結點&&面向對象設計思想](c語言實作)"  

    temp    =   source.decode('utf8')  

    print "同時比對中文英文"  

    print "--------------------------"  

    xx      =   u"([\w\w\u4e00-\u9fff]+)"  

    pattern =   re.compile(xx)  

    results =   pattern.findall(temp)  

    for result in results:  

        print result  

    print   

    print "隻比對中文"  

    xx      =   u"([\u4e00-\u9fff]+)"  

if __name__ == "__main__" :  

    # 測試正規表達式  

    reload(sys)  

    sys.setdefaultencoding("utf-8")  

    testrechinese( )  

   上面的代碼我們已經看的很明白了,這樣我們就很清楚了,那麼有沒有其他方法呢,其實python中也有一個其他方法可以解決中文比對的問題了,但是這個寫法其實是繞過了編碼問題,也就是說是一種有點投機取巧的方法,但是這個方法卻很實用。

轉載:http://blog.csdn.net/gatieme/article/details/43235791