Python正則表達式 re.sub()函數:標誌位flags與參數個數問題

這兩天在寫爬蟲程序,涉及英文文本處理,須要規範化英文標點符號的寫法。正常狀況下,英文句號「.」後面須要保證有且只有一個空格,但也有例外狀況,好比「i.e.」、「e.g.」、「P.S.」這種。因爲沒法預測大小寫,所以在正則表達式中使用了「標誌位」flags,卻死活不生效。html

一開始,個人函數是這樣寫的:python

1 def punctuate(s):
2     #----其他代碼暫略
3     s = re.sub(' e. g. ', 'e.g.', s, re.I)
4     return s

代碼的本意是:原本好好的「e.g.」,被函數前半斷的代碼錯改爲「e. g. 」以後,須要修復一下,將英文句號「.」後面的空格刪掉。但這行 re.sub() 代碼主要有2個問題:正則表達式

  1. 「e. g.」先後不必定是空格,所以這樣寫的話,若是遇到「e. g.,」或是「(e. g. xxx」的狀況就會被跳過。
  2. 英文的句號「.」未轉義
  3. 標誌位 re.I 不生效

前2個問題好解決。改進代碼以下:函數

1 def punctuate(s):
2     #----其他代碼暫略
3     s = re.sub('([^a-zA-Z]e\.) (g\.[^a-zA-Z])', '\g<1>\g<2>', s, re.I)
4     return s

規則是:「e. g.」以前或以後,必須有「非英文字母」的字符(包括空格),且「e.」和「g.」中間有一個空格,則將中間的空格刪掉,且保留先後的「非英文字母」(\g<1>表示查找到的第1個括號內的文本,\g<2>表示第2個括號)。但標誌位 re.I 的問題仍是沒解決。spa

後來翻到了「Python--詳解Python中re.sub」這篇文章,才頓悟:re.sub() 函數有5個參數,我傳入了4個參數,最後一個被認爲是第4個參數,而不是第5個!多麼低級的錯誤啊!.net

查閱「Python官方文檔」可知,code

re.sub(pattern, repl, string, count=0, flags=0)htm

我傳入的第4個參數 re.I 會被看成是 count。所以,正確的姿式是明確寫明「flags=re.I」。blog

整個標點符號規範化函數還包括其它的替換,完整代碼以下:文檔

 1 def punctuate(s):
 2     s = re.sub('([,:;?!\.」\)])', '\g<1> ', s) #後加空格
 3     s = re.sub('([「\(])', ' \g<1>', s) #前加空格
 4     s = re.sub('([「\(]) ', '\g<1>', s) #後刪空格
 5     s = re.sub(' ([,:;?!\.」\)])', '\g<1>', s) #前刪空格
 6     s = re.sub('([,\.?!;\)]) 」', '\g<1>」', s) #閉引號前去空格
 7     s = re.sub('\) ([,:;?!\.」])', ')\g<1>', s) #閉括號後去空格
 8     s = re.sub('(\d)\. (\d)', '\g<1>.\g<2>', s) #小數點後去空格
 9     s = re.sub(' +', ' ', s) #多空格改單空格
10     #拉丁加點縮寫單詞,點號後面去空格
11     s = re.sub('([^a-zA-Z]e\.) (g\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
12     s = re.sub('([^a-zA-Z]i\.) (e\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
13     s = re.sub('([^a-zA-Z]q\.) (v\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
14     s = re.sub('([^a-zA-Z]v\.) (s\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
15     s = re.sub('([^a-zA-Z]n\.) (b\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
16     s = re.sub('([^a-zA-Z]p\.) (s\.[^a-zA-Z])', '\g<1>\g<2>', s, flags=re.I)
17     s = re.sub('\. ,', '.,', s)
18     return s

 

 多麼痛的領悟!

相關文章
相關標籤/搜索