Jieba分詞包(一)——解析主函數cut


1. 解析主函數cut

    Jieba分詞包的主函數在jieba文件夾下的__init__.py中,在這個py文件中有個cut的函數,這個就是控制着整個jieba分詞包的主函數。
    cut函數的定義如下:
def cut(sentence,cut_all=False,HMM=True):

其給出的官方注釋為:    
'''The main function that segments an entire sentence that contains 
    Chinese characters into seperated words. 
    Parameter:
        - sentence: The String to be segmented
        - cut_all: Model. True means full pattern, false means accurate pattern.   
        - HMM: Whether use Hidden Markov Model.
    '''
說白了就是,其中sentence是需要分詞的句子樣本;cut_all是分詞的模式,稍微鑽研過分詞的小伙伴們都知道,jieba分詞有全模式和精准模式兩種,分別用true和false來選擇,默認是false也就是精准模式;HMM就是隱馬爾可夫鏈,這個是在分詞的理論模型中用到的,默認是開啟的。

下面我就接着cut函數中的注釋,來說一下cut函數的整體框架和局部細節。

def cut(sentence,cut_all=False,HMM=True):
#整個分詞的主函數,
#輸入sentence是需要分詞的句子;
#cut_all是分詞模式,默認是精准模式;
#HMM是隱馬爾可夫鏈,默認開啟。
'''The main function that segments an entire sentence that contains
Chinese characters into seperated words.
Parameter:
- sentence: The String to be segmented
- cut_all: Model. True means full pattern, false means accurate pattern.
- HMM: Whether use Hidden Markov Model.
'''
if not isinstance(sentence, unicode): #如果輸入的句子不是統一編碼形式的unicode,那么使用Python中的decode,將其解碼稱為unicode
#注:unicode、gbk等都是中文編碼的方式
try:
sentence = sentence.decode('utf-8')
except UnicodeDecodeError: #如果在decode的過程中出現了錯誤,那么就解碼成gbk形式的。
sentence = sentence.decode('gbk','ignore')
'''
\u4E00-\u9FA5a-zA-Z0-9+#&\._ : All non-space characters. Will be handled with re_han
\r\n|\s : whitespace characters. Will not be Handled.
'''
#下面使用到了Python中正則表達式模塊re,正則表達式是用於處理字符串的強大工具,
#擁有自己獨特的語法以及一個獨立的處理引擎,效率上可能不如str自帶的方法,但功能十分強大。
#其最擅長的、最被大家使用的就是字符串匹配功能
#正則表達式的大致匹配過程是:依次拿出表達式和文本中的字符比較,如果每一個字符都能匹配,則匹配成功;
#一旦有匹配不成功的字符則匹配失敗。如果表達式中有量詞或邊界,這個過程會稍微有一些不同

#re.compile 可以把正則表達式編譯成一個正則表達式對象。
#可以把那些經常使用的正則表達式編譯成正則表達式對象,這樣可以提高一定的效率
#關於正則表達式指南:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
#關於正則表達式常用的處理函數:http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898075.html

re_han, re_skip = re.compile(ur"([\u4E00-\u9FA5a-zA-Z0-9+#&\._]+)", re.U), re.compile(ur"(\r\n|\s)", re.U)
#將以下正則表達式編譯成re_han對象:
#\u4E00-\u9FA5是所有漢字的編碼,a-zA-Z是所有大小寫字母的編碼,0-9是所有阿拉伯數字的編碼,+#&\._其余字符
#將以下正則表達式編譯成re_skip對象:
#\r是回車,\n是換行,|或, \s是空白字符(\r\n\t\f\v)
#re.U是使得compile的結果取決於unicode定義的字符屬性
if cut_all:
re_han, re_skip = re.compile(ur"([\u4E00-\u9FA5]+)", re.U), re.compile(ur"[^a-zA-Z0-9+#\n]", re.U)
#全模式下,只handle中文字符部分[\u4E00-\u9FA5],其余的字母、數字等等都要跳過。
blocks = re_han.split(sentence)
#這個split的作用和Python自帶的split作用差不多,按照能夠匹配的子串,即剛才compile進去的哪些字符,將sentence分割
#而且是把sentence分成幾個blocks,然后針對每一塊進行分詞
'''
例子:
p = re.compile(r'\d+')
print p.split('one1two2three3four4')

### output ###
# ['one', 'two', 'three', 'four', ''] #按照compile的表達式,把一個string分成幾個blocks
'''
if HMM: #默認情況使用__cut_DAG作為分詞函數,為每個block分詞
cut_block = __cut_DAG
else:
cut_block = __cut_DAG_NO_HMM
if cut_all:
cut_block = __cut_all

for blk in blocks: #針對每一塊進行分詞
if len(blk)==0: #當blk為空時,繼續下一個blk的分詞
continue
if re_han.match(blk): #如果re_han.match(blk)為true,說明當前blk是re_han范圍內的文本
for word in cut_block(blk): #__cut_DAG作為分詞函數為每個block分詞,返回分詞后word列表
yield word #yield作用也是返回,但是其不會消除local variables。
#yield statement is what makes a function a generator function.
#具體的yield和return在Python中的區別:http://blog.csdn.net/jiyanfeng1/article/details/8148561
else:
tmp = re_skip.split(blk) #按照re_skip中的正則表達式,把blk划分成幾塊
for x in tmp:
if re_skip.match(x):
yield x #返回匹配划分的每一部分
elif not cut_all: #如果是精准模式,則返回x中的每一項,即試圖將句子最精確地切開
for xx in x:
yield xx
else: #如果是全模式,把句子中所有的可以成詞的詞語都掃描出來
yield x
---------------------
作者:bigface1234fdfg
來源:CSDN
原文:https://blog.csdn.net/puqutogether/article/details/40740473
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

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



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