最近在專案中遇到乙個問題,就是需要採用正則匹配一些疑似暗鏈和掛馬的html**,而公司的老大給的正規表示式有的地方寫的不夠嚴謹,導致在匹配的時候發生卡死的現象,而後面的邏輯自然無法執行了。雖然用正規表示式來判斷暗鏈和掛馬可能不那麼準確或者行業內很少有人那麼做,但是本文不討論如何使用正確的姿勢判斷暗鏈掛馬,只關注與正則超時的處理。
在使用正規表示式的時候,如果正則寫的太糟糕,所消耗的時間是驚人的,並且有可能會一直回溯,而產生卡死的現象,所以一般的大型公司都會有專門的人來對正則進行優化,從而提高程式效率。一般來說如果可能的話不要讓使用者來輸入正則進行匹配。但是現在既沒有專門的人進行正則的優化,本人也對正則了解的不夠,所以只能從另外的角度來考慮處理超時的問題。
首先我想到的方法是另外開啟乙個執行緒來進行匹配,而在主線程中進行等待,如果發現子執行緒在規定的時間內沒有返回就kill掉子執行緒。這也是乙個方案,但是我現在要介紹另外一種方案,該方案來自我在網上看到的一篇部落格.
部落格位址
該部落格給出了另外一種辦法,就是採用訊號的方式,在正則匹配之前定義乙個訊號,並規定觸犯時間和處理的函式,如果在規定時間內程式沒有結束那麼觸發乙個timeouterror的異常,而主線程收到這個異常時就會中斷執行,並處理這個異常,這樣就從正則匹配中解脫出來,達到了我們要的結果。這個方法有兩個不足之處:
訊號這個東西是linux獨有的,在windows下不適用
訊號只能在主線程中使用,而如果在子執行緒中進行正則匹配,那麼這個方法就不適用
import re
import multiprocessing
import signal
def time_out(b, c):
raise timeouterror
def search_with_timeout(pipe, word, value):
signal.signal(signal.sigalrm, time_out)
signal.alarm(1)
r = re.compile(word)
try:
ret = r.search(value, re.i)
b_ret = true if ret != none else false
pipe.send(b_ret)
except timeouterror:
pipe.send(false)
在上面的**中先的定義了乙個訊號,給定1s中以後觸發,觸發的函式為time_out然後執行正規表示式,如果在這1s中內無法完成,那麼處理函式會被呼叫,會跑出乙個異常,此時主線程終止當前任務的執行,進入到異常處理流程,這樣就可以終止正則匹配,從而正常的返回。由於這個部分是乙個新程序自然就涉及到不同程序之間的通訊,在這個例子中我使用了管道進行通訊。由於python在建立子程序的時候可以進行引數的傳入所以我只需要乙個管道將資料從子程序中寫入,再從朱金城中讀取就好了。
下面是呼叫該子程序的**:
pipe = multiprocessing.pipe()
p = multiprocessing.process(target = search_with_timeout, args = (pipe[0], word, left_value))
p.start()
p.join() #等待程序的結束
ret = pipe[1].recv() #獲取管道中的資料
Python處理正規表示式超時的辦法
最近在專案中遇到乙個問題,就是需要採用正則匹配一些疑似暗鏈和掛馬的html 而公司的老大給的正規表示式有的地方寫的不夠嚴謹,導致在匹配的時候發生卡死的現象,而後面的邏輯自然無法執行了。雖然用正規表示式來判斷暗鏈和掛馬可能不那麼準確或者行業內很少有人那麼做,但是本文不討論如何使用正確的姿勢判斷暗鏈掛馬...
python處理正規表示式
一.正規表示式 正規表示式是乙個用特殊符號表示的字串行,用來檢查乙個字串是否與某種字串模式匹配。較常用的正規表示式有 正規表示式 匹配物件 普通字元 匹配對應的字元 n匹配換行符 t匹配製表符 d匹配十進位制數字 d匹配除了十進位制數字的其他字元 w匹配字母,數字,下劃線 w匹配除了字母,數字,下劃...
正規表示式處理字元(Python)
匹配任意乙個字元,除了換行符 匹配0個或多個表示式 匹配1個或多個表示式 匹配任意長度字串 s匹配任意空白字元,等價於 t n r f s匹配任意非空字元 w匹配字母數字和下劃線 d匹配任意數字 精確匹配n個前面表示式 如 d 匹配字串開頭 匹配字串結尾 內建庫re re.match re.matc...