今天看了一個設計文檔,是關於怎麼設計一個數據庫表來模擬配置環境的,覺得設計的挺好的,估計能和數據庫原理那本書對上。看了一天,頭有點大,回家前寫篇Perl學習筆記吧,就當翻譯作業好了。Todd在公司Wiki上建了一個Page,裏面有他寫的一些很實用的腳本,以後再學。
目的 :匹配數字(Numeric),可以是整型,可以是浮點,可以是科學計數,有可能帶正負號。
我先摘錄一下整體思路,這個思路不限於匹配數字,這是一個構建正則 表達式的通用思路:
- 詳細的表述需求(Specify the tasks in detail)
- 把問題分解成子問題(Breaking down the problem into smaller parts)
- 把子問題用正則表達式表示出來(Translating the small parts into regexps)
- 整合用於解決子問題的正則表達式(Combining the regexps)
- 優化整個後的結果(Optimizing the final combined regexp)
其實很多東西都是相通的,所以要多學涉獵一些學科。上面提出來的5個步驟在算法導論中也提到過,這就是典型的Divide and Conquer的思路。或許現實生活中碰到的很多問題也是這樣的思路呢。好了,不說廢話了,我們一步步來:
Step1:在目的裏面已經比較詳細了,再補充一點,我們還可以換一個角度考慮,有時候不能正面表述一個事物的時候可以用反面來描述,比如,匹配數字就意味着不能匹配字符串!
Step2:子問題再目的中也給的比較明確,一共就兩類,整數和浮點數,每一類都有可能是使用科學計數法的,有可能是帶正負號的。而且正負號一定出現在開頭/^/,而指數部分一定出現在結尾/$/。
Step3:正負號是可選的,所以是/[+-]?/。整數的表達是/d+/。小數比較複雜,有3種形式,比如12., .12, 1.2 。對應這3種情況,分別寫出正則表達式: /d+./, /.d+/和/d+.d+/。所以對於無指數部分的浮點數表達就是:
/[+-]?(d+.| .d+| d+.d+)/ ,我們來試驗一下下:perl -e ‘print $1 if 123.45=~/[+-]?(d+.| .d+| d+.d+)/’;我們希望匹配123.45,可是結果是匹配123. !!爲什麼呢,問題出在匹配的時候,有多條道路選擇的時候,從左邊開始走,只要走通,就不去嘗試其他的選擇了。因爲123.已經匹配了,所以就不去看下面的了,就錯了!在使用’|'操作時一定要小心,儘量把條件更嚴格(更精確匹配)的表達式放在前面。這裏我們必須把/d+.d+/放在/d+./的前面。
-bash-3.00$ perl -e ‘print $1 if 123.45=~/[+-]?(d+.d+|d+.|.d+)/’
123.45
現在就剩下指數部分了,/([eE][+-]?d+)?/,注意指數也是有正負的哦,而且指數部分是可選的!
Step4:從邏輯上講,這道題目可以表達成 /^(optional sign)(integer|f.p. mantissa)(optional exponent)$/;所以最後的正則表達式就是:
/^[+-]?(d+.d+|d+.|.d+|d+)([eE][+-]?d+)?$/
Step5:這裏倒沒有什麼優化的地方,有一點提一下,一定要寫註釋,不然過幾天,自己都看不懂了-:)