2013-10-03 91 views
-1

你怎麼寫,從-214748.00-214748214748.00相匹配的貨幣的數值範圍內的正則表達式?正則表達式匹配表達式貨幣數值範圍

我試過這個,但沒有工作。

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

我要問,如果你有一些數字,爲什麼你是使用正則表達式? – drobert

+0

我的要求是限定人數,如果超過上限,然後我需要拋出一個異常 –

+0

這是最絕對不是正則表達式的工作。你會用螺絲刀敲釘子嗎?沒有容易的方式來寫一個正則表達式來驗證的數處於範圍,除非範圍限制是10次冪(即-100000 <= X <= 100000) –

回答

5

Nonono。你正在使用錯誤的工具來完成這項工作。正則表達式只是一個文本處理工具。解釋文本的含義是不好的。在識別需要處理的文本的語義時,這就是正則表達式不好的地方。

你應該使用簡單的語言工具和操作員來完成這項工作。除此之外,如果你處理的貨幣,避免使用doublefloat。它們沒有足夠的精度來準確地表示所有的浮點數。改爲使用BigDecimal


警告:請,永遠不要用這個這類問題:
注:這不處理浮點數。

既然你堅持了這麼多,我想出了下面的正則表達式,其適用於某些輸入我測試過。我想這將很好地工作在給定範圍內的任何整數值:

"-?(\\d{1,5}|1\\d{5}|2(?:0\\d{4}|1(?:[0-3]\\d{3}|4(?:[0-6]\\d{2}|7(?:[0-3]\\d|4[0-8])))))" 

-?裝置負數可選-

演示代碼:

String str = "-?(\\d{1,5}|1\\d{5}|2(?:0\\d{4}|1(?:[0-3]\\d{3}|4(?:[0-6]\\d{2}|7(?:[0-3]\\d|4[0-8])))))"; 

System.out.println("214748".matches(str)); // true 
System.out.println("214746".matches(str)); // true 
System.out.println("2148".matches(str)); // true 
System.out.println("-21448".matches(str)); // true 
System.out.println("-214747".matches(str)); // true 
System.out.println("214749".matches(str)); // false 

正則表達式使用了以下的事實。對於範圍[-214748, 214748]

  • 任何5個或更少位數字是有效的 - \\d{1,5}
  • 不限6開始與1位數是有效的 - 1\\d{5}
  • 用於開始2一個號碼:
    • 另外5開始0位數字是有效的 - 20\\d{4}
    • 如果旁邊的數字21
      1. 任何進一步的4個開始以[0-3]號碼是有效的 - 21[0-3]\\d{3}
      2. 爲了啓動與4任何進一步的4位數字: 開始[0-6]
        • 號碼是有效的 - 214[0-6]\d{2}
        • 如果4後位是7,然後
          1. [0-3]開頭的任何其他號碼均有效 - 2147[0-3]\\d
          2. 如果後位74,然後範圍[0-8]4後是有效的 - 21474[0-8]
+1

@Downvoter關注意見。 –

+1

@NullUserException。我沒有回答提供解決方案。我剛剛添加了爲什麼不應該使用正則表達式,並且給出了一個應該使用什麼的概念。我希望OP至少能夠和運營商一起完成這項工作。 –

+1

夠公平的。但是在忍者編輯之前我就低估了答案 – NullUserException

1

這裏有一個工作正則表達式,做你問什麼:

^-?((([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7])))))([.][0-9]{2})?)|214748([.]00)?)$ 

這在很大程度上依賴於下面的子正則表達式,它從0到214747的範圍相匹配:

([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7]))))) 

爲什麼從0至214747,而不是0到214748?因爲這樣做,避免匹配214748.01至214748.99(+/-)的值將更容易。打破正則表達式,我們得到:

^ # match start of line 
-? # optional minus sign 
    (# match one of the following groups, this one: 
    (
    ([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7]))))) 
    # the sub-regex above matches the range from 0 to 214747 
    ([.][0-9]{2})? # this matches the optional two decimals 
    ) 

    | # or this one: 
    214748([.]00)? # 214748, with optional zeroes 
) 
$ # match end of line 

有你有它,一個過於複雜的正則表達式,這是一個噩夢來看待,更不用說維護了。如果您需要更改範圍,則需要大量工作。

我希望這個畸形鼓勵該任務的使用正則表達式。像其他人所說的那樣使用適當的工具進行處理。如果正則表達式爲要求,告訴他們這是一個可怕的想法,並要求他們修復要求。