今天遇到一個 bug:一個用來抽取 iso 檔案並加以分析的 python script,錯誤回報說在該 iso 找不到必要的檔案 intrd.lz ,但我手動使用指令去抽取該 iso 檔,確認了裡面明明就有這個檔案。
後來發現 bug 在於以往成功提取資訊的時候,該 script 利用下面正規表示,分析下面的字串:
file_re = re.compile( "(?P[ldrwx-]{10})\s+\d+\s+\d+\s+\d+\s+\d+\s[A-Za-z]{3}"+ "\s+\d+\s\d+\s+\[\s+\d+\s\d\d\](\s\s(?P.*))?")
其實就是這串
(?P[ldrwx-]{10})\s+\d+\s+\d+\s+\d+\s+\d+\s[A-Za-z]{3} \s+\d+\s\d+\s+\[\s+\d+\s\d\d\](\s\s(?P.*))?
去分析
-r--r--r-- 1 0 0 16242610 Aug 9 2013 [ 601511 00] initrd.lz目的是希望可以分別找出匹配字串「-r--r--r--」與「initrd.lz」。
而出問題的是,當 script 嘗試去分析這個字串的時候,沒有得到預期的答案。
-r--r--r-- 1 0 0 16437443 Nov 12 2013 [1062241 00] initrd.lz
請注意會引起問題的字串中,有個被標示成紅色的「1」,相對於不會引起問題的字串,那個地方是個空白。所以要解決這個 bug ,只要把原本硬性描述「該空白處必須是一個或是多個空白」而使用「\s+」,換成「該地方可以是空白或是數字」。以下兩個方法在這個問題中等價,都可以匹配出第一個 pattern 是 「-r--r--r--」而第二個是「initrd.lz」。
原本的字串:標紅色表示要被修改的部份 (?P[ldrwx-]{10})\s+\d+\s+\d+\s+\d+\s+\d+\s[A-Za-z]{3}\s+\d+\s\d+\s+\[\s+\d+\s\d\d\](\s\s(?P 解法一:改成「一個空白」加上一個星號 (?P.*))? [ldrwx-]{10})\s+\d+\s+\d+\s+\d+\s+\d+\s[A-Za-z]{3}\s+\d+\s\d+\s+\[ *\d+\s\d\d\](\s\s(?P 解法二:注意「0-9」的前面也有一個空白,使用數字 5、8 是給實際數字位數一點容忍量,在這個案例中,一個 7 就夠用了。 (?P.*))? [ldrwx-]{10})\s+\d+\s+\d+\s+\d+\s+\d+\s[A-Za-z]{3}\s+\d+\s\d+\s+\[[ 0-9]{5,8}\s\d\d\](\s\s(?P .*))?
附錄資料:
- 好用的線上正規表示式解讀器;若完全只用人腦翻譯真的實在太辛苦了。
- https://atedev.wordpress.com/2007/11/23/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%A4%BA%E5%BC%8F-regular-expression/
- http://notepad.yehyeh.net/Content/Program/RegularExpression/8.php
- http://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F
- http://stackoverflow.com/questions/18701992/regex-space-or-no-space
- python 2 的 re module 說明文件
- 簡易語法參考:
- \s 一個空白,\s+ 多個空白
- \d 一個數字,\d+ 多個數字
- \[ 跳脫字元和一個「[」,表示我想要匹配「[」
- * 星號表示星號前面的元素有沒有出現、而且可以出現多次。一個空白加一個星號就是「有沒有空白無所謂,也可以有多個空白」
- [ 0-9]{5,8} 允許一個空白(注意 0 前面有個空白)、數字零到九,並且只匹配出現那樣的元素 5 到 8 個。
沒有留言:
張貼留言