2016-09-21 53 views
2

我在一堆維基百科頁面上使用正則表達式。實際上,對於第一頁這樣的20頁來說,它確實非常好,但之後它突然凍結,而我沒有看到原因。中斷腳本提供了這一點:Python正則表達式與小輸入字符串凍結

File "imageListFiller.py", line 30, in getImage 
foundImage = re.search(urlRegex, str(decodedLine)) 
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/re.py",line 173, in search 
return _compile(pattern, flags).search(string) 

這是我的代碼:

def getImage(wikiHtml): 
    urlRegex = """File:((?:[a-zA-Z]|[0-9]|[[email protected]&+]|[!*\(\),]|(?:[0-9a-fA-F][0-9a-fA-F]))*?\.(png|jpg|svg|JPG))""" 
uselessPictures = ("Wiktionary-logo-v2.svg", "Disambig_gray.svg", 
        "Question_book-new.svg", "Commons-logo.png")  

for line in wikiHtml: 
    decodedLine = line.decode('utf-8') 
    foundImage = re.search(urlRegex, str(decodedLine)) 
    if foundImage: 
     if not foundImage.group(1) in uselessPictures: 
      return foundImage.group(1) 

,這是導致其凍結輸入字符串:

HREF =「/維基/文件: EARTH _-_ WIKIPEDIA_SPOKEN_ARTICLE_(Part_01).ogg「title =」聽這篇文章「> src =」// upload.wikimedia.org/wikipedia/commons/thumb/4/47/Sound-icon.svg/20px-Sound-icon .svg.png「width =」20「height =」15「srcset =」// upload.wikimedia.org/wikipedia/commons/thumb/4/47/Sound-icon.svg/30px-Sound-ic on.svg.png 1.5x,//upload.wikimedia.org/wikipedia/commons/thumb/4/47/Sound-icon.svg/40px-Sound-icon.svg.png 2x「data-file-width =」 128「data-file-height =」96「> />

正則表達式實際上不應該在這裏匹配,它只是需要跳過這一行。 謝謝!

+0

僅供參考:需要注意的是'[$ -_]'匹配所有ASCII大寫字母和數字,更。如果你逃脫連字符,它已經更安全了。 –

+0

你(或更好的表達)容易發生災難性的回溯:https://regex101.com/r/eH4nJ2/1 – Jan

+1

爲什麼不簡單地'([^ /] * \。(png | jpg | svg | JPG)) ' – fabianegli

回答

1

模式中的$-_部分創建了匹配大寫字母和數字以及更多字符的範圍。由於該組中的其他分支可能會在相同的位置(如[a-zA-Z])匹配,導致超時/災難性回溯問題。

你只需要對第一組中只匹配1個字符的所有字符類進行連接,或者在字符類中跳出-或者將它放在字符類的開始/結尾處(我仍然會逃脫如果它的模式將會在未來被更新):

r"""File:((?:[0-9a-fA-F]{2}|[a-zA-Z0-9\[email protected]&+!*(),])*?\.(png|jpg|svg|JPG))""" 

regex demo

此外,較長的替代方案應該在較短的一個之前,所以[0-9a-fA-F]{2}應該先走。

此外,\w可以用來縮短模式的位(更換[a-zA-Z0-9_]):

r"""File:((?:[0-9a-fA-F]{2}|[\w\[email protected]&+!*(),])*?\.(png|jpg|svg|JPG))""" 
          ^^^ 
相關問題