我正在开发一个Rails应用程序,该应用程序使用一些事件数据的外部提要,但很烦人的是,它们只提供带有时间的字符串。例如:
晚上7:30开门,演出从晚上9点开始
我的目标是从这些字符串中提取第一次,并将其放入datetime字段中。系统需要捕获以下类型的值:
上午11点
下午12点
下午1点
下午2:15
下午3.30
4.45
5:30
06:15
晚上07:30
晚上8:30
下午9.15
但不是这些:
105
2 50
305下午
4 15点
下午74
840am
我认为执行此操作的最佳方法是使用正则表达式,并通过一些搜索(尤其是此SO问题),我得到了以下内容:
[0-9]{1,2}(:|.)??[0-9]{0,2}\s?(am|pm|AM|PM)
它部分起作用,但不排除我不想要的任何字符,似乎只捕获了2和3中am / pm的第一个字符。
正则表达式可能吗?
谢谢!
也许是这样的:
^[01]?[0-9]([:.][0-9]{2})?(\s?[ap]m)?$
示范
请注意,这不会处理24小时的时间,并且关于12小时的时间也没有特别的规定,即可以匹配19pm
。
如果您想更具体一点,可以尝试:
^((0?[0-9]|1[012])([:.][0-9]{2})?(\s?[ap]m)|([01]?[0-9]|2[0-3])([:.][0-9]{2})?)$
示范
或尝试将其作为更大一部分文本的一部分进行匹配,则可以使用如下所示的内容:
\b((0?[1-9]|1[012])([:.][0-5][0-9])?(\s?[ap]m)|([01]?[0-9]|2[0-3])([:.][0-5][0-9]))\b
示范
\b((?:0?[1-9]|1[0-2])(?!\d| (?![ap]))[:.]?(?:(?:[0-5][0-9]))?(?:\s?[ap]m)?)\b
它不支持24小时制,但会强制执行有效时间。将不区分大小写的标志添加到您的正则表达式引擎中,无论它是哪种语言,或者(i: )
如果支持则用正则表达式包装。
样品演示
正则表达式:
NODE EXPLANATION -------------------------------------------------------------------------------- \b the boundary between a word char (\w) and something that is not a word char -------------------------------------------------------------------------------- ( group and capture to \1: -------------------------------------------------------------------------------- (?: group, but do not capture: -------------------------------------------------------------------------------- 0? '0' (optional (matching the most amount possible)) -------------------------------------------------------------------------------- [1-9] any character of: '1' to '9' -------------------------------------------------------------------------------- | OR -------------------------------------------------------------------------------- 1 '1' -------------------------------------------------------------------------------- [0-2] any character of: '0' to '2' -------------------------------------------------------------------------------- ) end of grouping -------------------------------------------------------------------------------- (?! look ahead to see if there is not: -------------------------------------------------------------------------------- \d digits (0-9) -------------------------------------------------------------------------------- | OR -------------------------------------------------------------------------------- ' ' -------------------------------------------------------------------------------- (?! look ahead to see if there is not: -------------------------------------------------------------------------------- [ap] any character of: 'a', 'p' -------------------------------------------------------------------------------- ) end of look-ahead -------------------------------------------------------------------------------- ) end of look-ahead -------------------------------------------------------------------------------- [:.]? any character of: ':', '.' (optional (matching the most amount possible)) -------------------------------------------------------------------------------- (?: group, but do not capture (optional (matching the most amount possible)): -------------------------------------------------------------------------------- (?: group, but do not capture: -------------------------------------------------------------------------------- [0-5] any character of: '0' to '5' -------------------------------------------------------------------------------- [0-9] any character of: '0' to '9' -------------------------------------------------------------------------------- ) end of grouping -------------------------------------------------------------------------------- )? end of grouping -------------------------------------------------------------------------------- (?: group, but do not capture (optional (matching the most amount possible)): -------------------------------------------------------------------------------- \s? whitespace (\n, \r, \t, \f, and " ") (optional (matching the most amount possible)) -------------------------------------------------------------------------------- [ap] any character of: 'a', 'p' -------------------------------------------------------------------------------- m 'm' -------------------------------------------------------------------------------- )? end of grouping -------------------------------------------------------------------------------- ) end of \1 -------------------------------------------------------------------------------- \b the boundary between a word char (\w) and something that is not a word char