Python 正則表達式匹配中文


參照Python正則表達式指南

在使用Python的過程中,由於需求原因,我們經常需要在文本或者網頁元素中用Python正則表達式匹配中文,但是我們經常所熟知的正則表達式卻只能匹配英文,而對於中文編碼卻望塵莫及,於是我大量Google,幾經Baidu,花了兩個多個小時測試,終於發現解決的辦法。特記錄如下

從字符串的角度來說,中文不如英文整齊、規范,這是不可避免的現實。本文結合網上資料以及個人經驗,以 python 語言為例,稍作總結。歡迎補充或挑錯。 
通常我們可以使用 repr()函數查看字串的原始格式。這對於寫正則表達式有所幫助。 

Python正則表達式的問題

更加詳細的Python正則表達式問題,請參見這里http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

    Python 的 re模塊有兩個相似的函數:re.match(), re.search 。

    兩個函數的匹配過程完全一致,只是起點不同。
    match只從字串的開始位置進行匹配,如果失敗,它就此放棄;

    而search則會鍥而不舍地完全遍歷整個字串中所有可能的位置,直到成功地找到一個匹配,或者搜索完字串,以失敗告終。

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

    從一堆文本中,找出所有可能的匹配,以列表的形式返回,這種情況用findall()這個函數。例子見后面的代碼。 

UTF-8與unicode

    UTF-8 是變長的,1-6個字節,少數是漢字每個占用3個字節,多數占用4個字節,正則式為[\x80-\xff]{3},這個都知道了吧。 
    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吧

示例程序1

# -*- 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 "--------"
print m
print m.group()
print "--------\n"
 
#unicode
s = unicode(s)
print "原始unicode字符"
print "--------"
print repr(s)
print "--------\n"
 
#unicode chinese
re_words = re.compile(u"[\u4e00-\u9fa5]+")
m =  re_words.search(s,0)
print "unicode 中文"
print "--------"
print m
print m.group()
res = re.findall(re_words, s)       # 查詢出所有的匹配字符串
if res:
    print "There are %d parts:\n"% len(res) 
    for r in res: 
        print "\t",r 
        print 
print "--------\n"
 
 
#unicode korean
re_words=re.compile(u"[\uac00-\ud7ff]+")
m =  re_words.search(s,0)
print "unicode 韓文"
print "--------"
print m
print m.group()
print "--------\n"
 
 
#unicode japanese katakana
re_words=re.compile(u"[\u30a0-\u30ff]+")
m =  re_words.search(s,0)
print "unicode 日文 片假名"
print "--------"
print m
print m.group()
print "--------\n"
 
 
#unicode japanese hiragana
re_words=re.compile(u"[\u3040-\u309f]+")
m =  re_words.search(s,0)
print "unicode 日文 平假名"
print "--------"
print m
print m.group()
print "--------\n"
 
 
#unicode cjk Punctuation
re_words=re.compile(u"[\u3000-\u303f\ufb00-\ufffd]+")
m =  re_words.search(s,0)
print "unicode 標點符號"
print "--------"
print m
print m.group()
print "--------\n"

 

 

幾種主要非英文字符集的編碼范圍

下面是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]+$也是一樣的結果。

示例程序2

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

 

#!coding:utf-8
 
import re
import sys
 
 
 
# 測試匹配中文信息
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 
    print 
    print "只匹配中文"
    print "--------------------------"
    xx      =   u"([\u4e00-\u9fff]+)"
    pattern =   re.compile(xx)
    results =   pattern.findall(temp)
 
    for result in results:
        print result
    print "--------------------------"
 
if __name__ == "__main__" :
    # 測試正則表達式
 
    reload(sys)
    sys.setdefaultencoding("utf-8")
 
    TestReChinese( )

 

 

 

其他方法


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

具體信息請參見http://blog.csdn.net/gatieme/article/details/43275077

 

 

轉:
https://blog.csdn.net/gatieme/article/details/43235791

 

 

\w 匹配的僅僅是中文,數字,字母,對於國人來講,僅匹配中文時常會用到,見下

代碼如下:
匹配中文字符的正則表達式: [\u4e00-\u9fa5]



或許你也需要匹配雙字節字符,中文也是雙字節的字符
代碼如下:
匹配雙字節字符(包括漢字在內):[^\x00-\xff]



注:可以用來計算字符串的長度(一個雙字節字符長度計 2,ASCII 字符計 1 )

 

 

PS:關於正則,本站還提供了一個非常簡便實用的正則測試工具供大家使用:

正則表達式在線測試工具://www.w3cschool.cn/tools/index?name=reg


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM