最近看到Java高手老紫竹寫的《判斷數字是否為double的Regex》,我近來也在學Regex的應用,所以來發揮發揮。這裡用perl指令碼寫,因為它支援Regex比較好。讓我們一步一步來解刨double浮點數: 普通的整數都是合法double型,帶上尾碼字母d或者D也是double型。比如: 1 +10 -100 100d 987D 因此用Regex:
^[-+]?/d[dD]$
來匹配。 double型的變數還能儲存實數。比如: 1.0 +12.34 -45.896 -563.887d 甚至 124. .123 -.687 在Java中也都是合法double值。 1)如果小數點前有整數的話,那小數點和小數的出現可以隨意; 2)如果小數點前面沒有數位話,預設以0做整數,但小數必須出現。也就是說,只有一個小數點的話,那就是非法的double數。因此,我們要用多選分支來做:
^[-+]?(/d+(/./d*)?|/./d+)[dD]?$
double變數還有一種,用科學計數法。指數部分只能是十進位整數,允許為負數。比如: 1e123 12.546e54d 4335.546E33 -.54e-7D 因此還要在尾部加上指數的匹配。指數沒有小數,所以只要匹配整數就可以。
^[-+]?(/d+(/./d*)?|/./d+)([eE][-+]?/d+)?[dD]?$
最後,也是最麻煩的,就是Java中double的取值範圍:負數範圍:從-1.7976931348623157×10+308到-4.94065645841246544×10-324 正數範圍:從4.94065645841246544×10-324到1.7976931348623157×10+308 這也就是說,指數的取值範圍在 -324 到 308 之間。如果僅僅是這樣,那還好說,關鍵是前面的小數還這麼複雜。為了簡化問題,我就把指數的範圍在 -323 到 307 之間,對前面的小數沒有限制。那首先來匹配 -307 到 307
[-+]?([012]?/d{1,2}|30[0-7])
然後另外在匹配 -308 到 -324
-3([01]?[4-9]|[012]?[0-3])
合并起來,就是:
^[-+]?(/d+(/./d*)?|/./d+)([eE]([-+]?([012]?/d{1,2}|30[0-7])|-3([01]?[4-9]|[012]?[0-3])))?[dD]?$
用這個Regex來編寫一個perl指令碼:
#!/usr/bin/perlwhile ($line = <STDIN>){chomp($line);if ($line =~ /^[-+]?(/d+(/./d*)?|(/./d+))([eE]([-+]?([012]?/d{1,2}|30[0-7])|-3([01]?[4-9]|[012]?[0-3])))?[dD]?$/){print $line, " is Java double!/n";}else{print $line, " is not Java double/n";}}
測試資料:
+-.ea1..10.1-.-.1+.11e123d-3.543E4456D-45.54879e-323d-777.1234E-3244553.876e3571543e30713.54e15.78d213.e123d1.2.3-.1.1+ee12
輸出
+ is not Java double- is not Java double. is not Java doublee is not Java doublea is not Java double1. is Java double!.1 is Java double!0.1 is Java double!-. is not Java double-.1 is Java double!+.1 is Java double!1e123d is Java double!-3.543E4456D is not Java double-45.54879e-323d is Java double!-777.1234E-324 is not Java double4553.876e357 is not Java double1543e307 is Java double!13.54e15.78d is not Java double213.e123d is Java double!1.2.3 is not Java double-.1.1 is not Java double+e is not Java doublee12 is not Java double
著作權聲明
本人的所有原創文章皆保留著作權,請尊重原創作品。
轉載必須包含本聲明,保持本文完整,並以超連結形式註明原始作者“redraiment”和主要站台上的本文原始地址。 連絡方式
我的郵箱,歡迎來信(redraiment@gmail.com)
我的Blogger(子清行)
我的Google Sites(子清行)
我的CSDN部落格(夢婷軒)
我的百度空間(夢婷軒)