日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

Python处理正则表达式超时的办法

發(fā)布時(shí)間:2025/3/20 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python处理正则表达式超时的办法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近在項(xiàng)目中遇到一個(gè)問(wèn)題,就是需要采用正則匹配一些疑似暗鏈和掛馬的HTML代碼,而公司的老大給的正則表達(dá)式有的地方寫(xiě)的不夠嚴(yán)謹(jǐn),導(dǎo)致在匹配的時(shí)候發(fā)生卡死的現(xiàn)象,而后面的邏輯自然無(wú)法執(zhí)行了。雖然用正則表達(dá)式來(lái)判斷暗鏈和掛馬可能不那么準(zhǔn)確或者行業(yè)內(nèi)很少有人那么做,但是本文不討論如何使用正確的姿勢(shì)判斷暗鏈掛馬,只關(guān)注與正則超時(shí)的處理。

在使用正則表達(dá)式的時(shí)候,如果正則寫(xiě)的太糟糕,所消耗的時(shí)間是驚人的,并且有可能會(huì)一直回溯,而產(chǎn)生卡死的現(xiàn)象,所以一般的大型公司都會(huì)有專門(mén)的人來(lái)對(duì)正則進(jìn)行優(yōu)化,從而提高程序效率。一般來(lái)說(shuō)如果可能的話不要讓用戶來(lái)輸入正則進(jìn)行匹配。但是現(xiàn)在既沒(méi)有專門(mén)的人進(jìn)行正則的優(yōu)化,本人也對(duì)正則了解的不夠,所以只能從另外的角度來(lái)考慮處理超時(shí)的問(wèn)題。
首先我想到的方法是另外開(kāi)啟一個(gè)線程來(lái)進(jìn)行匹配,而在主線程中進(jìn)行等待,如果發(fā)現(xiàn)子線程在規(guī)定的時(shí)間內(nèi)沒(méi)有返回就kill掉子線程。這也是一個(gè)方案,但是我現(xiàn)在要介紹另外一種方案,該方案來(lái)自我在網(wǎng)上看到的一篇博客.

博客地址:https://blog.lilydjwg.me/2013/5/25/set-a-time-limit-for-python-regex-matching.39335.html

該博客給出了另外一種辦法,就是采用信號(hào)的方式,在正則匹配之前定義一個(gè)信號(hào),并規(guī)定觸犯時(shí)間和處理的函數(shù),如果在規(guī)定時(shí)間內(nèi)程序沒(méi)有結(jié)束那么觸發(fā)一個(gè)TimeoutError的異常,而主線程收到這個(gè)異常時(shí)就會(huì)中斷執(zhí)行,并處理這個(gè)異常,這樣就從正則匹配中解脫出來(lái),達(dá)到了我們要的結(jié)果。這個(gè)方法有兩個(gè)不足之處:

  • 信號(hào)這個(gè)東西是Linux獨(dú)有的,在Windows下不適用

  • 信號(hào)只能在主線程中使用,而如果在子線程中進(jìn)行正則匹配,那么這個(gè)方法就不適用

  • 我的項(xiàng)目正在運(yùn)行在Linux系統(tǒng)上,所以針對(duì)第一個(gè)不足來(lái)說(shuō)可以接受,但是我的正則匹配都是在子線程中,所以乍看之下這個(gè)方案也不太靠譜,但是好在我在后面的評(píng)論中發(fā)現(xiàn)博主給出了針對(duì)第二種不足的解決方案——開(kāi)辟一個(gè)子進(jìn)程,將正則匹配放到子線程中,這樣一來(lái)可以充分利用多核(畢竟Python中的多線程是個(gè)偽多線程),二來(lái)可以分方便的使用該方案解決問(wèn)題,下面是實(shí)際的代碼

    ''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)! ''' import re import multiprocessing import signaldef time_out(b, c):raise TimeoutErrordef 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 Falsepipe.send(b_ret)except TimeoutError:pipe.send(False)

    在上面的代碼中先的定義了一個(gè)信號(hào),給定1s中以后觸發(fā),觸發(fā)的函數(shù)為time_out然后執(zhí)行正則表達(dá)式,如果在這1s中內(nèi)無(wú)法完成,那么處理函數(shù)會(huì)被調(diào)用,會(huì)跑出一個(gè)異常,此時(shí)主線程終止當(dāng)前任務(wù)的執(zhí)行,進(jìn)入到異常處理流程,這樣就可以終止正則匹配,從而正常的返回。由于這個(gè)部分是一個(gè)新進(jìn)程自然就涉及到不同進(jìn)程之間的通信,在這個(gè)例子中我使用了管道進(jìn)行通信。由于Python在創(chuàng)建子進(jìn)程的時(shí)候可以進(jìn)行參數(shù)的傳入所以我只需要一個(gè)管道將數(shù)據(jù)從子進(jìn)程中寫(xiě)入,再?gòu)闹旖鸪侵凶x取就好了。
    下面是調(diào)用該子進(jìn)程的代碼:

    pipe = multiprocessing.Pipe() p = multiprocessing.Process(target = search_with_timeout, args = (pipe[0], word, left_value)) p.start() p.join() #等待進(jìn)程的結(jié)束 ret = pipe[1].recv() #獲取管道中的數(shù)據(jù)

    總結(jié)

    以上是生活随笔為你收集整理的Python处理正则表达式超时的办法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。