我编写了以下正则表达式
(1[012]|[1-9])(am|pm)\-(1[012]|[1-9])(am|pm)
要匹配以下类型的时间格式:
7am-10pm (matches correctly and creates 4 match groups 7, am, 10, pm)
13am-10pm (this should not be matched, however it matches and creates 4 match groups 3, am, 10, pm)
10pm (this doesn't match as expected because it doesn't specify the time range end)
111am-10pm (this should not be matched, however it matches and creates 4 match groups 11, am, 10, pm)
我如何改进我的正则表达式,使我不需要重复数字和am/pm模式,并且还可以这样做:
注意:我正在使用Ruby2.2.1
谢谢。
发布于 2015-04-14 12:02:24
首先让我们看看你做错了什么:
13 am -10 pm(这不应该匹配,但它匹配,并创建4个匹配组3,上午,10,下午)
它只匹配适当的时间,如上午111分或下午13时等,应视为不匹配。
这是匹配的,因为您允许在这里匹配单个数字1-9:(1012\1-9)。
为了解决这个问题,你要么允许一个1-9位数字,要么允许1+ 0-2.因为我们不知道正则表达式何时开始,所以我们将使用一些单词边界来确保我们有一个“单词开始”。
由于您不想捕获数字,但是在整个时间加上am\pm,您可以使用一个非捕获组:
\b((?:1[0-2]|[1-9])
然后,简单地重复我们自己,加上一个破折号:
\b((?:1[0-2]|[1-9])[ap]m)-((?:1[0-2]|[1-9])[ap]m)
关于第3点,是的,你可以用正则表达式来做这件事,但是只要你得到第1组和第2组,看看时间范围是否真的有意义,你就会更好地加入一个逻辑检查。
所有这些都是你得到的:
# \b((?:1[0-2]|[1-9])[ap]m)-((?:1[0-2]|[1-9])[ap]m)
#
#
# Assert position at a word boundary «\b»
# Match the regular expression below and capture its match into backreference number 1 «((?:1[0-2]|[1-9])[ap]m)»
# Match the regular expression below «(?:1[0-2]|[1-9])»
# Match either the regular expression below (attempting the next alternative only if this one fails) «1[0-2]»
# Match the character “1” literally «1»
# Match a single character in the range between “0” and “2” «[0-2]»
# Or match regular expression number 2 below (the entire group fails if this one fails to match) «[1-9]»
# Match a single character in the range between “1” and “9” «[1-9]»
# Match a single character present in the list “ap” «[ap]»
# Match the character “m” literally «m»
# Match the character “-” literally «-»
# Match the regular expression below and capture its match into backreference number 2 «((?:1[0-2]|[1-9])[ap]m)»
# Match the regular expression below «(?:1[0-2]|[1-9])»
# Match either the regular expression below (attempting the next alternative only if this one fails) «1[0-2]»
# Match the character “1” literally «1»
# Match a single character in the range between “0” and “2” «[0-2]»
# Or match regular expression number 2 below (the entire group fails if this one fails to match) «[1-9]»
# Match a single character in the range between “1” and “9” «[1-9]»
# Match a single character present in the list “ap” «[ap]»
# Match the character “m” literally «m»
发布于 2015-04-14 11:46:44
您在正则表达式中缺少了^
(行的开始),这就是为什么它是从中间匹配的。
你必须使用:
^(1[012]|[1-9])(am|pm)\-(1[012]|[1-9])(am|pm)
更好的解决方案:如果模式不总是从新行开始,也可以使用\b
(边界)。
\b(1[012]|[1-9])(am|pm)\-(1[012]|[1-9])(am|pm)\b
见演示。
https://stackoverflow.com/questions/29635841
复制