模式在ruby中匹配时间



我为以下时间格式构建了一个模式匹配4:05am or 11:03pm

它在rubular上工作,但irb没有找到匹配。我该怎么修理它?

irb(main):568:0> "4:00am" =~ /[d+:d{2}(a|p)m]/

=比;0

如注释中所述,您已经将regex放在括号中,这表示字符类。很容易修复。

irb(main):001:0> "4:00am" =~ /d+:d{2}(a|p)m/
=> 0

但这也适用于:

irb(main):002:0> "4:70am" =~ /d+:d{2}(a|p)m/
=> 0

相反,您可能希望指定:可以后跟数字0-5,然后后跟任何数字。

irb(main):005:0> "4:50am" =~ /d+:[0-5]d(a|p)m/
=> 0
irb(main):006:0> "4:70am" =~ /d+:[0-5]d(a|p)m/
=> nil

但这仍然可以检测到像"14:40am"这样的疯狂时间。考虑到它在AM/PM拾取,我们可以假设一个12小时的时钟并进一步修改您的正则表达式:

irb(main):009:0> "14:40am" =~ /^(d|1[0-2]):[0-5]d(a|p)m$/
=> nil
irb(main):010:0> "12:40am" =~ /^(d|1[0-2]):[0-5]d(a|p)m$/
=> 0

如果您需要一个完整的正则表达式来匹配时间值,我们可以使用Regexp::Common::time Perl模块中的正则表达式。您可以通过安装模块并打印$RE{time}{hms}来获得。

(?:(?<!d)(?:(?:(?=d)(?:[01]d|2[0123]|(?<!d)d)))[:.x20](?:(?:[0-5]d))(?:[:.x20](?:dd))?(?:s?(?:(?:(?=[AaPp])(?:[ap](?:m|.m.)?|[AP](?:M|.M.)?))))?)

小时取值范围为0 ~ 24。分值和秒值必须在0到59之间,并且必须是两位数字(即,如果小于10,它们必须有前导零)。

小时、分、秒可以用冒号、句号或空格分隔。

"seconds"值可以省略。

时间后面可以跟一个"am/pm"指标;即,下列值之一:

a am a.m. p PM p.m.上午1点。

时间与am/pm指示符之间可能有空格。

3.1.2 :018 > re = %r{(?:(?<!d)(?:(?:(?=d)(?:[01]d|2[0123]|(?<!d)d)))[:.x20](?:(?:[0-5]d))(?:[
:.x20](?:dd))?(?:s?(?:(?:(?=[AaPp])(?:[ap](?:m|.m.)?|[AP](?:M|.M.)?))))?)}
=> /(?:(?<!d)(?:(?:(?=d)(?:[01]d|2[0123]|(?<!d)d)))[:.x20](?:(?:[0-5]d))(?:[:.x20](?:... 
3.1.2 :019 > re.match('12:59 a.m.')
=> #<MatchData "12:59 a.m."> 
3.1.2 :020 > re.match('12:59 a.m. and stuff')
=> #<MatchData "12:59 a.m."> 
3.1.2 :021 > re.match('12:59 z.m.')
=> #<MatchData "12:59"> 
3.1.2 :022 > re.match('13:59 a.m.')
=> #<MatchData "13:59 a.m."> 
3.1.2 :023 > re.match('99:59 a.m.')
=> nil 
3.1.2 :024 > re.match('11:60 a.m.')
=> nil 
3.1.2 :026 > re.match('4:12')
=> #<MatchData "4:12"> 
3.1.2 :027 > re.match('4:1')
=> nil 

最新更新