2016-04-15 10 views
0

我需要匹配一個數字範圍:可以重構這個數字範圍的正則表達式嗎?

-9223372036854775808

^(?:922337203685477580[0-7]|9223372036854775[0-7]\d{2}|922337203685477[0-4]\d{3}|92233720368547[0-6]\d{4}|9223372036854[0-6]\d{5}|922337203685[0-3]\d{6}|92233720368[0-4]\d{7}|9223372036[0-7]\d{8}|922337203[0-5]\d{9}|92233720[0-2]\d{10}|922337[0-1]\d{12}|92233[0-6]\d{13}|9223[0-2]\d{14}|922[0-2]\d{15}|92[0-1]\d{16}|9[01]\d{17}|[1-8]\d{18}|\d{0,18}|-(?:922337203685477580[0-8]|9223372036854775[0-7]\d{2}|922337203685477[0-4]\d{3}|92233720368547[0-6]\d{4}|9223372036854[0-6]\d{5}|922337203685[0-3]\d{6}|92233720368[0-4]\d{7}|9223372036[0-7]\d{8}|922337203[0-5]\d{9}|92233720[0-2]\d{10}|922337[0-1]\d{12}|92233[0-6]\d{13}|9223[0-2]\d{14}|922[0-2]\d{15}|92[0-1]\d{16}|9[01]\d{17}|[1-8]\d{18}|\d{0,18}))?$ 

// space for easier copy and paste 

是的,我知道這聽起來很瘋狂,但有一個很長的故事背後。我不知道如何通過檢查一個範圍,因爲數字的大小,在JavaScript中做到這一點,這必須是準確的。

這是打破這件事的思考過程。我剛開始使用最大數量,然後開始工作,然後在正則表達式中加入 - 來處理負數。你顯然必須在某處複製並粘貼這個東西才能看到它。另外,可能是錯誤。讓我的頭幾乎爆炸。

  • 9,223,372,036,854,775,807
  • 922337203685477580 [0-7]
  • 9223372036854775 [0-7] [0-9] {2}
  • 922337203685477 [0-4] [0-9] {3}
  • 92233720368547 [0-6] [0-9] {4}
  • 9223372036854 [0-6] [0-9] {5}
  • 922337203685 [0-3] [0-9] {6 }
  • 92233720368 [0-4] [0-9] {7}
  • 9223372036 [0-7] [0-9] {8}
  • 922337203 [0-5] [0-9] {9}
  • 92233720 [0-2] [0-9] {10 }
  • 922337 [0-1] [0-9] {12}
  • 92233 [0-6] [0-9] {13}
  • 9223 [0-2] [0-9] { 14}
  • 922 [0-2] [0-9] {15}
  • 92 [0-1] [0-9] {16}
  • 9 [01] [0-9] {17 }
  • [1-8] [0-9] [18]
  • [0-9] {0,18}

有在負與正不同的一個數字,所以你會看到我必須基本上覆制大部分。

那麼幾個問題:

  1. 難道我這樣做對嗎?
  2. 如果不是,有什麼更好的方法?
  3. 考慮到數字的大小,這可以在沒有正則表達式的情況下完成嗎?我需要驗證客戶端。
  4. 它可以重構,仍然保留嚴格的規則?

建議表示讚賞:)

回答

3

可以這樣不考慮數的大小正則表達式完成?

它可以在只使用字符串操作(不需要轉換爲數字)的一系列if語句中完成。

  • 不匹配的所有字符串[0-9] {1,19}超出

  • 是長度爲18以下的所有候選者是良好

  • 爲長度19你可以用字符串比較工作,看看它們在數值上比你的上限值以下

  • 調整上述取負數的護理

+0

我不是專業的性能測試。我確實想過把它分解成一系列「if」陳述。你認爲這樣做會更好嗎?如果性能較差,我可能會選擇將它放在一個大的正則表達式中,因爲其他許多原因都不值得我的問題混淆。 – user1447679

+0

性能差異可能很小(考慮到程序的其餘部分)。我會避免大的正則表達式爲可讀性。 – Thilo

+0

瘋狂的想法將字符串分解成已知的塊,然後比較具有已知數值範圍的單獨字符串,即數字-20 x1 || li1 === x1 && li2> x2),那麼這個數字低於允許的下限。只是一個想法。如果問題太大而無法解決。把它分解成更小的片斷 –

0

你的正則表達式是正確的。 這是一個較短的版本

^(?:-9223372036854775808|-?(?:\d{0,18}|(?!922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9])\d{19}))$

Regex demo

如何不產生錯誤,正則表達式:
輸入最大數:

9223372036854775807 

Output:

9223372036854775807 
922337203685477580 
92233720368547758 
9223372036854775 
922337203685477 
92233720368547 
9223372036854 
922337203685 
92233720368 
9223372036 
922337203 
92233720 
9223372 
922337 
92233 
9223 
922 
92 
9 

替換最後一個數字字母

9->remove all line 
8->9 
7->[8-9] 
6->[7-9] 
5->[6-9] 
4->[5-9] 
3->[4-9] 
2->[3-9] 
1->[2-9] 
0->[1-9] 

Output:

922337203685477580[8-9] 
92233720368547758[1-9] 
92233720368547759 
922337203685477[6-9] 
92233720368547[8-9] 
9223372036854[8-9] 
922337203685[5-9] 
92233720368[6-9] 
92233720369 
922337203[7-9] 
92233720[4-9] 
9223372[1-9] 
922337[3-9] 
92233[8-9] 
9223[4-9] 
922[4-9] 
92[3-9] 
9[3-9] 

Regex [Output]
922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9]

添加這些[輸出]以正則表達式

(?! 輸出)\ d {19}

Will become [output2]

(?!922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9])\d{19}

相配\d{19} < = 9223372036854775807

添加

^(?: - 9223372036854775808 | - ?(?:\ d {0,18} | [OUTPUT2]))$

^(?:-9223372036854775808|-?(?:\d{0,18}|(?!922337203685477580[8-9]|92233720368547758[1-9]|92233720368547759|922337203685477[6-9]|92233720368547[8-9]|9223372036854[8-9]|922337203685[5-9]|92233720368[6-9]|92233720369|922337203[7-9]|92233720[4-9]|9223372[1-9]|922337[3-9]|92233[8-9]|9223[4-9]|922[4-9]|92[3-9]|9[3-9])\d{19}))$

將匹配

-9223372036854775808
+/- \d{0,18}
+/- \d{19} < = 9223372036854775807

Demo

+0

這看起來非常棒。我需要仔細檢查一下,因爲我沒有立即理解你正在採取的所有步驟。在我睡了幾個小時後會報告回來:)非常感謝。 – user1447679

+0

我更新了更多解釋以加深理解。 –

相關問題