试图构建一个正则表达式来检查模式

时间:2011-12-22 05:20:43

标签: regex

a)以数字开头和结尾 b)连字符应以数字开头和结尾 c)逗号应以数字开头和结尾 d)数量范围应为1-31

[编辑:在正则表达式中需要此规则,谢谢Ed-Heal!]
e)如果数字以连字符( - )开头,则不能以逗号以外的任何其他字符结尾并遵循上面列出的所有规则。
例如。 2-2,1或2,2-1有效而1-1-1-1无效

例如
a)1-5,5,15-29
b)1,28,1-31,15
c)15,25,3 [编辑:用3替换56,谢谢你指出Brian!] d)1-24,5-6,2-9

试过这个,但即使字符串以逗号开头,它也会通过:

/^[0-9]*(?:-[0-9]+)*(?:,[0-9]+)*$/

7 个答案:

答案 0 :(得分:3)

这个怎么样?这将至少检查规则a,b和c,但不检查规则d。

/^[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*$/

如果您需要确保所有数字都在1-31范围内,那么表达式将会变得更加丑陋:

/^([1-9]|[12][0-9]|3[01])(-([1-9]|[12][0-9]|3[01]))?(,([1-9]|[12][0-9]|3[01])(-([1-9]|[12][0-9]|3[01]))?)*$/

请注意,您的示例c包含的数字56不在1-31范围内,因此它不会传递第二个表达式。

答案 1 :(得分:0)

这是我的工作

编号:

0|([1-9][0-9]*)调用此表达式A 注意此表达式将零视为特殊情况,并防止以零开头的数字,例如0000001234

数字或范围:

A|(A-A)将此表达式称为B(即(0|([1-9][0-9]*))|((0|([1-9][0-9]*))-(0|([1-9][0-9]*)))

逗号操作员

B(,B)*

这样做可以解决问题,我们得到了

((0|([1-9][0-9]*))|((0|([1-9][0-9]*))-(0|([1-9][0-9]*))))(,((0|([1-9][0-9]*))|((0|([1-9][0-9]*))-(0|([1-9][0-9]*)))))*

您可以使用\d [0-9]

来缩短这一点

答案 2 :(得分:0)

试试这个

^\d+(-\d+)?(,\d+(-\d+)?)*$

DEMO

答案 3 :(得分:0)

其他方法并未限制允许的数字范围。这只允许1到31,而且似乎比人们提出的一些怪物更简单......

^([12][0-9]?|3[01]?|[4-9])([-,]([12][0-9]?|3[01]?|[4-9]))*$

没有检查合理的范围;添加这将使表达式显着更复杂。最后,使用更简单的正则表达式并在代码中实现完整性检查可能会更好。

答案 4 :(得分:0)

在我之前的答案中使用相同的逻辑,但限制了范围

A成为[1-9]\d|3[01] B变为([1-9]\d|3[01])|(([1-9]\d|3[01])-([1-9]\d|3[01]))

总体表达

(([12]\d|3[01])|(([12]\d|3[01])-([12]\d|3[01])))(,(([12]\d|3[01])|(([12]\d|3[01])-([12]\d|3[01]))))*

答案 5 :(得分:0)

我建议使用以下正则表达式:

(?<number>[1-9]|[12]\d|3[01]){0}(?<thing>\g<number>-\g<number>|\g<number>){0}^(\g<thing>,)*\g<thing>$

它看起来很糟糕但它不是:)实际上构造(?<name>...){0}允许我们定义一个命名的正则表达式,并说它与定义它的位置不匹配。因此,我为名为number的数字定义了一个模式,并为我称为事物的模式定义了模式,即称为thing的范围或数字。接下来我知道你的表达式是这些事物的序列,所以我使用命名的正则表达式thing来构造它\g<thing>。它给出了(\g<thing>,)*\g<thing>。这很容易阅读和理解。如果你允许空格在你的正则表达式中是非重要的,你甚至可以这样缩进:

(?<number>[1-9]|[12]\d|3[01]){0}
(?<thing>\g<number>-\g<number>|\g<number>){0}
^(\g<thing>,)*\g<thing>$/

我用Ruby 1.9.2测试过它。您的正则表达式引擎应该支持命名组以允许这种清晰度。

irb(main):001:0> s1 = '1-5,5,15-29'
=> "1-5,5,15-29"
irb(main):002:0> s2 = '1,28,1-31,15'
=> "1,28,1-31,15"
irb(main):003:0> s3 = '15,25,3'
=> "15,25,3"
irb(main):004:0> s4 = '1-24,5-6,2-9'
=> "1-24,5-6,2-9"
irb(main):005:0> r = /(?<number>[1-9]|[12]\d|3[01]){0}(?<thing>\g<number>-\g<number>|\g<number>){0}^(\g<thing>,)*\g<thing>$/
=> /(?<number>[1-9]|[12]\d|3[01]){0}(?<thing>\g<number>-\g<number>|\g<number>){0}^(\g<thing>,)*\g<thing>$/
irb(main):006:0> s1.match(r)
=> #<MatchData "1-5,5,15-29" number:"29" thing:"15-29">
irb(main):007:0> s2.match(r)
=> #<MatchData "1,28,1-31,15" number:"15" thing:"15">
irb(main):008:0> s3.match(r)
=> #<MatchData "15,25,3" number:"3" thing:"3">
irb(main):009:0> s4.match(r)
=> #<MatchData "1-24,5-6,2-9" number:"9" thing:"2-9">
irb(main):010:0> '1-1-1-1'.match(r)
=> nil

答案 6 :(得分:0)

此主题的最佳正则表达式可能是:

^(?'int'[1-2]?[1-9]|3[01])((,\g'int')|(-\g'int'(?=$|,)))*$

demo