2009-11-16 44 views
1

我正在使用ExtJS。一個與ExtJS的部件製成應該允許逗號分隔數/ opeator串(3個類似的例子)等修改數字和數字範圍表達式的正則表達式

1, 2-3, 4..5, <6, <=7, >8, >=9 
>2, 3..5, >=9,>10 
<=9, 1, <=8, 4..5, 8-9 

在這裏,我使用equals文本字段,範圍的( - ),序列(..)大於/等於大於&運營商的數字小於或等於100.這些數字用逗號分隔。

什麼可以是這種類型的字符串的正則表達式?

對於我以前問的問題..我從 「dlamblin」 的解決方案: ^(?:\d+(?:(?:\.\.|-)\d+)?|[<>]=?\d+)(?:,\s*\d+(?:(?:\.\.|-)\d+)?|[<>]=?\d+)*$

這完美的作品針對所有模式除外:

  1. 只有關係運算符(<<=>,>=)作爲字符串的第一個元素存在。例如。 <=3, 4-5, 6, 7..8工作完美,但<=3, 4-5, 6, 7..8, >=5關係運算符不在字符串的第1個元素。

  2. 也字符串<3<4, 5, 9-4不會給出任何錯誤,即它是令人滿意的條件,雖然<3<4之間需要逗號。

  3. 數字串中應小於或等於100。即<1000-10099..100

  4. 它不應該允許前導零(如003099

+0

你是指正整數不大於100,或者是0和負數是允許的嗎? – 2009-11-16 18:26:16

+0

字符串中的數字只能在0到100之間。 – user211607 2009-11-16 18:31:36

回答

9
廢料

那並改用分詞器。用逗號分割字符串,然後查看每個令牌並決定(可能使用正則表達式)它是哪種類型的關係。如果它不存在任何關係,則它是無效的。如果任何關係中包含的數字太大,則無效。

爲了您的理智和在完成該操作後必須維護此代碼的人員,請不要使用正則表達式來驗證這樣複雜的相互關聯的一組規則。把它分解成更簡單的塊。

2

Welbog's advice使用標記器是理智的選擇。

如果你有一個強制的正則表達式其他一些限制,你可以使用

^(<|<=|>|>=)?\s*(100|0|[1-9]\d?)((\.\.|-)(100|0|[1-9]\d?))?(,\s*(<|<=|>|>=)?\s*(100|0|[1-9]\d?)((\.\.|-)(100|0|[1-9]\d?))?)*$ 

這就是手動擴展以下的結果:

num = (100|0|[1-9]\d?) 
op = (<|<=|>|>=) 
range = op?\s*num((\.\.|-)num)? 
expr = ^range(,\s*range)*$ 
+0

+1用於捕捉Tim無法捕捉的[1-9] \ d?'部分。這兩個答案一起作出了體面的正則表達式答案。儘管這不是一個好的選擇。 – Welbog 2009-11-16 18:55:43

1

這應該工作:

^(?:(?:\s*((?:\<|\>|\<\=|\>\=)?(?:[1-9]|[1-9]\d|100))\s*(?:,|$))|(?:\s*((?:[1-9]|[1-9]\d|100)(?:\.\.|\-)(?:[1-9]|[1-9]\d|100))\s*(?:,|$)))*$ 

(顯然,您需要使用「多行」選項。)

如果您有支持「忽略空白」選項正則表達式引擎的優勢,那麼你可以打破它是這樣的:

^       # beginning of line 
(?: 
    (?: 
    \s*      # any whitespace 
    (      # capture group 
     (?:<|>|<=|>=)?  # inequality 
     (?:[1-9]|[1-9]\d|100) # single value 
    ) 
    \s*      # any whitespace 
    (?:,|$)     # comma or end of line 
) 
    | 
    (?: 
    \s*      # any whitespace 
    (      # catpure group 
     (?:[1-9]|[1-9]\d|100) # single value 
     (?:\.\.|\-)   # range modifier 
     (?:[1-9]|[1-9]\d|100) # single value 
    ) 
    \s*      # any whitespace 
    (?:,|$)     # comma or end of line 
) 
)+       # one or more of all this 
$       # end of line 

正如你所看到的,你的例子匹配快報:

http://imgur.com/5ctQS.png

+0

+1。如果你在這種情況下必須使用正則表達式,請爲激光的喜愛記錄它。 – Welbog 2009-11-16 18:54:27

+0

誰不喜歡激光‽ – 2009-11-16 19:00:18

1

我Welbog同意,前/後處理應該是更好的選擇。

但因爲我喜歡RegEx所以這裏是我的解決方案。

^[ \t]*(?:(?:0|[1-9][0-9]?|100)(?:(?:\-|\.\.)(?:0|[1-9][0-9]?|100))?|(?:[<>]=?)(?:0|[1-9][0-9]?|100))(?:[ \t]*,[ \t]*(?:(?:0|[1-9][0-9]?|100)(?:(?:\-|\.\.)(?:0|[1-9][0-9]?|100))?|(?:[<>]=?)(?:0|[1-9][0-9]?|100)))*[ \t]*$

\s」不使用,因爲它在某些發動機可包括「\n」。

'\d'未使用,因爲您將需要[1-9]因此[0-9]將更易於使用。

'(?:0|[1-9][0-9]?|100)'將匹配0到100之間的一個數字,而不是前導零。

'(?:[&lt;&gt;]=?)(?:0|[1-9][0-9]?|100)'將匹配條件後跟一個數字(如果您還想匹配'=',只需調整它即可)。

'(?:0|[1-9][0-9]?|100)(?:(?:\-|\.\.)(?:0|[1-9][0-9]?|100))?'將匹配具有可選範圍或序列的數字。

充分說明:

^ 
[ \t]* // Prefix spaces 
(?: // A valid term 
    // A number 
    (?:0|[1-9][0-9]?|100) 
    // Optional range or sequence 
    (?: 
     (?:\-|\.\.) 
     (?:0|[1-9][0-9]?|100) 
    )? 
    | 
    // Condition and number 
    (?:[<>]=?)(?:0|[1-9][0-9]?|100) 
) 
(?: // Other terms 
    [ \t]*,[ \t]* // Comma with prefix and suffix spaces 
    (?: // A valid term 
     // A number 
     (?:0|[1-9][0-9]?|100) 
     // Optional range or sequence 
     (?: 
      (?:\-|\.\.) 
      (?:0|[1-9][0-9]?|100) 
     )? 
     | 
     // Condition and number 
     (?:[<>]=?)(?:0|[1-9][0-9]?|100) 
    ) 
)* 
[ \t]* // Tail spaces 

我測試用正則表達式搜索的Eclipse和它的工作。

希望這會有所幫助。

+0

另一個體面的,但我會''s *'而不是'[\ t] *'趕上其他類型的空間(如一些鬼鬼祟祟的Unicode的)。 – Welbog 2009-11-16 18:58:07