首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >匹配时间范围,包括上午7时至晚上10时。

匹配时间范围,包括上午7时至晚上10时。
EN

Stack Overflow用户
提问于 2015-04-14 11:29:27
回答 2查看 1.5K关注 0票数 2

我编写了以下正则表达式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(1[012]|[1-9])(am|pm)\-(1[012]|[1-9])(am|pm)

要匹配以下类型的时间格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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模式,并且还可以这样做:

  1. 它只捕捉时间范围的组成部分,如上午7点-10点,应该只有2组比赛上午7点,10点。
  2. 它只匹配适当的时间,如上午111分或下午13时等,应视为不匹配。
  3. 我不知道是否可以用正则表达式,但是我们能不能使正则表达式匹配正确的时间范围,例如早上7点到下午1点应该匹配,但是下午4点到下午1点应该不匹配吗?

注意:我正在使用Ruby2.2.1

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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,您可以使用一个非捕获组:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
\b((?:1[0-2]|[1-9])

然后,简单地重复我们自己,加上一个破折号:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
\b((?:1[0-2]|[1-9])[ap]m)-((?:1[0-2]|[1-9])[ap]m)

关于第3点,是的,你可以用正则表达式来做这件事,但是只要你得到第1组和第2组,看看时间范围是否真的有意义,你就会更好地加入一个逻辑检查。

所有这些都是你得到的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# \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»
票数 1
EN

Stack Overflow用户

发布于 2015-04-14 11:46:44

您在正则表达式中缺少了^ (行的开始),这就是为什么它是从中间匹配的。

你必须使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
^(1[012]|[1-9])(am|pm)\-(1[012]|[1-9])(am|pm)

更好的解决方案:如果模式不总是从新行开始,也可以使用\b (边界)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
\b(1[012]|[1-9])(am|pm)\-(1[012]|[1-9])(am|pm)\b

演示

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29635841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文