話說,從當完兵後開始玩 CGI 由 C 到 Perl 到 PHP ,其實寫CGI 應用最常會用到正規表示法(通用運算式),可是我永遠學不會,因為我真的對於正規表示法有一種說不出來的厭惡感,它們長得不是很好看,不過從今天起,我試著要去接受它,看能不能愛上它,順便把之前沒有釐清的概念,再度釐清一下。今天就先看看數字檢查怎麼玩吧。
每個位數都要拆解
正規表示法處理數字時不能用 [0-255] 來代表範圍 0~255,如果以檢查 0~255 範圍為例子,這是一個最多有三個字元的字串。要把每個位數拆開來看。
如果要檢查的數字只有 1 位,也就是 0~9 的時候,這時候應該沒異議,就是 [0-9] 的表示法。
如果檢查的數字是到達 2 位,那麼就是 10~99,這時候十位數範圍是 1~9,個位數為 0~9,表示法則為 [1-9][0-9]。
若數字到達 3 位的時候,但最大值是 255,那麼範圍應該是 100~255,表示法 1[0-9][0-9]|2[0-4][0-9]|25[0-5]。到了三位數就比較複雜些了,其實可以拆開看, 1[0-9][0-9] 可以代表 100~199,2[0-4][0-9] 可以代表 200~249,25[0-5] 可以代表 250~255。
以上三種狀況各代表數字由 0~9 , 10~99 , 100~255 合併起來的完整正規表示法就變成
^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$
原來啊~檢查數字反正就是每一個位數去想想看它的範圍是落在多少,一個個拆開來寫 ><
理解了嗎 !!!!!!!!!!!!!!!!!! 啃,這就是我為何永遠學不會的原因,這比建構式數學還要複雜啊。
問號代表可有可無
再來更進階一點,如果要判斷 0(或000) ~ 255 呢,表示法為
^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$
這個表示法,多了問號的字元,代表可有可無啦,我把它拆成兩部分,[01]?[0-9]?[0-9] 和 2[0-4][0-9]|25[0-5]。
先看第一個部分 [01]?[0-9]?[0-9] ,這段先確認一件事情,它可以代表的數字為 0~199 或 000~199,所以為何要用到問號 "?" 來修飾懂了吧。所以這段表示法 0 , 1 , 02 , 12 , 003 , 023 , 123 都可以被檢查通過的。
第二個部分2[0-4][0-9]|25[0-5] 其實和最上面的 0~255 檢查的代碼是重複的,代表 200~249及250~255。
所以以上兩個部分合併起來就可以代表 0~199 或 000~199 , 200~249 及 250~255 ,一句話表示就是 0(或000)~255 了。
PHP 範例
<?php $numerics = array( '000', '255', '256', '0', '01', '-1', '+99', '99', '88', '-99', '-555', '123', '1000', ); $pattern = '/^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/'; echo "Check 0..255\n"; foreach($numerics as $numeric) { echo "Numeric $numeric is " . (preg_match($pattern, $numeric, $matches) ? 'true' : 'false') . "\n"; } $pattern = '/^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/'; echo "Check 0 or 000..255\n"; foreach($numerics as $numeric) { echo "Numeric $numeric is " . (preg_match($pattern, $numeric, $matches) ? 'true' : 'false') . "\n"; }
這段 PHP Code 馬上就可以測試上述兩個例子了,我現在還在思考,有正負號該怎麼判斷,等我有時間再來好好研究吧 哈哈。
英文好的人,可以參考 http://www.regular-expressions.info/numericranges.html 這個網址,主站其實有好多通用運算式規則及範例可以看,其實有太多英文字不認得我,我只能由實作後再和原文配看看寫成我自己看得懂的文字了。