Perl學習筆記–Building a RegExp

今天看了一個設計文檔,是關於怎麼設計一個數據庫表來模擬配置環境的,覺得設計的挺好的,估計能和數據庫原理那本書對上。看了一天,頭有點大,回家前寫篇Perl學習筆記吧,就當翻譯作業好了。Todd在公司Wiki上建了一個Page,裏面有他寫的一些很實用的腳本,以後再學。

 

目的 :匹配數字(Numeric),可以是整型,可以是浮點,可以是科學計數,有可能帶正負號。

我先摘錄一下整體思路,這個思路不限於匹配數字,這是一個構建正則 表達式的通用思路:

  1. 詳細的表述需求(Specify the tasks in detail)
  2. 把問題分解成子問題(Breaking down the problem into smaller parts)
  3. 把子問題用正則表達式表示出來(Translating the small parts into regexps)
  4. 整合用於解決子問題的正則表達式(Combining the regexps)
  5. 優化整個後的結果(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:這裏倒沒有什麼優化的地方,有一點提一下,一定要寫註釋,不然過幾天,自己都看不懂了-:)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章