我正在使用ExtJS。使用ExtJS组件制作的文本字段之一应该允许逗号分隔的数字/操作符字符串(3个类似示例),如
1, 2-3, 4..5, <6, <=7, >8, >=9
>2, 3..5, >=9,>10
<=9, 1, <=8, 4..5, 8-9
这里我使用的是equals,range( - ),sequence(..)&amp;对于小于或等于100的数字,大于/等于运算符。这些数字用逗号分隔。
这种类型的字符串的正则表达式是什么?
对于我之前提出的问题..我从“dlamblin”获得了一个解决方案:
^(?:\d+(?:(?:\.\.|-)\d+)?|[<>]=?\d+)(?:,\s*\d+(?:(?:\.\.|-)\d+)?|[<>]=?\d+)*$
这适用于所有模式,除了:
仅当关系运算符(<
,<=
,>
,>=
)作为字符串的第一个元素存在时。例如。 <=3, 4-5, 6, 7..8
工作正常,但<=3, 4-5, 6, 7..8, >=5
关系运算符不在字符串的第一个元素。
同时字符串<3<4, 5, 9-4
不会出现任何错误,即虽然<3
和<4
之间需要使用逗号,但条件仍然令人满意。
字符串中的数字应小于或等于100.即<100
,0-100
,99..100
不应允许前导零(例如003
,099
)
答案 0 :(得分:9)
废弃并使用标记器代替。用逗号分隔字符串,然后查看每个标记并决定(可能使用正则表达式)它是什么类型的关系。如果它不是现有的关系,则它是无效的。如果任何关系包含的数字太大,则无效。
为了您的理智以及在完成此代码后必须维护此代码的人员,请不要使用正则表达式来验证这种复杂的相互关联的规则集。把它分解成更简单的块。
答案 1 :(得分: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)*$
答案 2 :(得分: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
如您所见,它与Expresso中的示例匹配:
答案 3 :(得分: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之间的数字而不会导致零。
'(?:[<>]=?)(?: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的正则表达式搜索进行测试,它可以工作。
希望这有帮助。