2011-10-07 103 views
0

我想寫一個允許3位數字後跟可選小數的正則表達式,整數部分不能大於180或小於-180。有效輸入的例子是156.56,56.778,9,6.7等等。 到目前爲止,我想出了這個^(\+|-)?:180|1[0-7][0-9]|[0-9][0-9]|[0-9]?([\.][0-9]{1,3})?$,但是這些似乎也匹配了195.678。有限制的十進制數的正則表達式

回答

4

而不是這樣做,爲什麼不只是有兩個檢查?一個可以確保您匹配的模式,另可確保值是-180和180

之間

/-?\d{3}(\.\d{1,3})?/.test(val) && (val <= 180 && val >= -180) 
得到的溶液是更容易理解和維護,並就更不用說了,更理智的:) 。

您的正則表達式不起作用的原因是^$在整個模式中不匹配。您在正則表達式中有不同的條件,它們之間用|分隔。 ^與第一個選項關聯,並且$與最後一個選項關聯。在以下示例中很容易看出:

假設您有正則表達式/^[0-9][0-9]|[0-9]$/。如果你對12345進行了測試,你會得到什麼?您可能傾向於說它會返回false,但實際上它返回true。這是因爲有一個有效的匹配!在12345中的12將與^[0-9][0-9]匹配。所以你要說的是,你想匹配字符串開頭的任何兩個數字或字符串末尾的數字。基本上任何字符串至少有兩個數字開頭一個數字在最後會匹配。所以12abc會匹配,abc1

但是,如果將正則表達式更改爲/^([0-9][0-9]|[0-9])$/,則只會匹配一位和兩位數的數字。這是因爲字符串的開始和結束位於匹配組之外,這意味着整個組必須匹配。這是你在正則表達式中有條件時必須考慮的事情。

編輯

此外,蒂姆指出:

...有一個冒號它不應該是:^(+ | - )?:180場比賽:180, +:180或 - :180沒有別的

+1

同意。花式正則表達式可能會檢查值的限制,但它會比邏輯和更復雜。更不用說多少便宜的計算。 –

+0

Pfft,誰想要理智? – canon

+0

:)同意!我會接受你的ansewer。仍然想知道我做錯了什麼。 – user424134

0

既然你介紹一位的0,像這樣
應該驗證的整個範圍的可能性:

^(?:\+|-)?(?:180(?:\.0{0,3})?|(?:0{1,3}|0{0,2}[1-9]|0?[1-9][0-9]|1[0-7][0-9])(?:\.[0-9]{1,3})?)$

測試在Perl

use strict; 
use warnings; 


my $regex = qr/ 
^ 
(?:\+|-)? 
(?: 
     180 (?:\.0{0,3})? 
    | 
    (?: 
      0{1,3} 
     | 
      0{0,2}[1-9] 
     | 
      0?[1-9][0-9] 
     | 
      1[0-7][0-9] 
    ) 
    (?:\.[0-9]{1,3})? 
) 
$ 
/x; 


for ('000' .. '180') 
{ 
    my $num; 

    $num = -1 * $_; 
    if ($num =~ /$regex/) { print "$num\t" } 
      else { print "($num failed)\t" } 

    $num = 1 * $_; 
    if ($num =~ /$regex/) { print "$num\t" } 
      else { print "($num failed)\t" } 

    $num = '+' . $_ . ".$_"; 
    if ($num =~ /$regex/) { print "$num\t" } 
      else { print "($num failed)\t" } 

    $num = '-' . $_ . ".$_"; 
    if ($num =~ /$regex/) { print "$num\t" } 
      else { print "($num failed)\t" } 

    print "\n"; 
} 

輸出:

0  0  +000.000  -000.000 
-1  1  +001.001  -001.001 
-2  2  +002.002  -002.002 
-3  3  +003.003  -003.003 
-4  4  +004.004  -004.004 
-5  5  +005.005  -005.005 
-6  6  +006.006  -006.006 
-7  7  +007.007  -007.007 
-8  8  +008.008  -008.008 
-9  9  +009.009  -009.009 
-10  10  +010.010  -010.010 
-11  11  +011.011  -011.011 
-12  12  +012.012  -012.012 
-13  13  +013.013  -013.013 
-14  14  +014.014  -014.014 
-15  15  +015.015  -015.015 
-16  16  +016.016  -016.016 
-17  17  +017.017  -017.017 
-18  18  +018.018  -018.018 
-19  19  +019.019  -019.019 
-20  20  +020.020  -020.020 
-21  21  +021.021  -021.021 
-22  22  +022.022  -022.022 

<snipped> 

-172 172  +172.172  -172.172 
-173 173  +173.173  -173.173 
-174 174  +174.174  -174.174 
-175 175  +175.175  -175.175 
-176 176  +176.176  -176.176 
-177 177  +177.177  -177.177 
-178 178  +178.178  -178.178 
-179 179  +179.179  -179.179 
-180 180  (+180.180 failed)  (-180.180 failed)