Trying to build a regular expression to check pattern

后端 未结 7 832
我在风中等你
我在风中等你 2021-01-20 17:32

a) Start and end with a number
b) Hyphen should start and end with a number
c) Comma should start and end with a number
d) Range of number should be from 1-31

7条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-20 18:12

    I propose the following regex:

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

    It looks awful but it isn't :) In fact the construction (?...){0} allows us to define a named regex and to say that it doesn't match where it is defined. Thus I defined a pattern for numbers called number and a pattern for what I called a thing i.e. a range or number called thing. Next I know that your expression is a sequence of those things, so I use the named regex thing to build it with the construct \g. It gives (\g,)*\g. That's easy to read and understand. If you allow whitespaces to be non significant in your regex, you could even indent it like this:

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

    I tested it with Ruby 1.9.2. Your regex engine should support named groups to allow that kind of clarity.

    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 = /(?[1-9]|[12]\d|3[01]){0}(?\g-\g|\g){0}^(\g,)*\g$/
    => /(?[1-9]|[12]\d|3[01]){0}(?\g-\g|\g){0}^(\g,)*\g$/
    irb(main):006:0> s1.match(r)
    => #
    irb(main):007:0> s2.match(r)
    => #
    irb(main):008:0> s3.match(r)
    => #
    irb(main):009:0> s4.match(r)
    => #
    irb(main):010:0> '1-1-1-1'.match(r)
    => nil
    

提交回复
热议问题