從字元串的角度來說,中文不如英文整齊、規範,這是不可避免的現實。本文結合網上資料以及個人經驗,以 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吧
# -*- 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
#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]+$也是一樣的結果。
那麼我們很多時候如果要比對的内容如果既有中文也有英文,比如我們要比對一個可以由中文字母以及一些其他字元組成的标題,該怎麼寫呢,我麼接着看下面的代碼
#!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 "隻比對中文"
xx = u"([\u4e00-\u9fff]+)"
if __name__ == "__main__" :
# 測試正規表達式
reload(sys)
sys.setdefaultencoding("utf-8")
testrechinese( )
上面的代碼我們已經看的很明白了,這樣我們就很清楚了,那麼有沒有其他方法呢,其實python中也有一個其他方法可以解決中文比對的問題了,但是這個寫法其實是繞過了編碼問題,也就是說是一種有點投機取巧的方法,但是這個方法卻很實用。
轉載:http://blog.csdn.net/gatieme/article/details/43235791