2009-11-16 93 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