正则表达式以匹配时间跨度

时间:2009-08-05 12:50:33

标签: regex

我想解析可能包含混合模式的数据,例如

1-4pm
1pm-5pm
noon to 11pm
noon to midnight
etc.

我想提取开始和结束时间。我怎样才能通过正则表达式实现这一目标。我知道我不能支持所有可能的输入格式,但是如何才能实现支持最​​大值?


这是我的表达 的 ^(([AZ] +)?)\ S *([0-9] {1,2} [:]?[0-9] {0,2} \ S * [AM | PM | AM | PM] [] )\ S * [ - |。?到| \ | / | =] \ S (?([AZ] +)| ([0-9] {1,2} [:]?[。] [0-9] {0,2} \ S * [AM | PM | |上午下午] )) ?$

几乎涵盖了所有组合。我只是想知道这个正则表达式中是否有任何优化。 如果Timespan从中午,午夜等开始,或者我们可以像星期日一样忽略任何值,dayPart将使用所有起始非数字字符来处理。 如果存在,startTime将尝试以任何格式消费。同样适用于endPart和EndTime。

3 个答案:

答案 0 :(得分:2)

首先,定义一个匹配单个时间点的模式。根据您的示例,它可能类似于:

(noon|midnight|[0-9]+\s?(am|pm)?)

接下来,定义分隔符。也许:

(to|\-)

最后,将第一个中的两个与第二个中的一个组合。假设您的语言支持变量,例如:

set timePattern {(noon|midnight|[0-9]+\s?(am|pm)?)}
set separator {(to|\-)}
set fullPattern "$timePattern(\s*$separator\s*$timePattern)?"

一旦你通过引擎传递它,你应该能够得到匹配的表达式的部分。你可能需要让一些群体不被捕捉,但我会把它作为读者的练习。然后,您可能需要解析各个部分以确定时间。例如,将“1pm”解析为1和“pm”并基于此计算时间。

一旦你将它分解成这样就可以更容易地摆弄组成部分并使表达更容易理解。虽然,在支持带注释的多行表达式的某些语言中可以实现同样的目的。

答案 1 :(得分:1)

根据语言,您可以“建立”匹配模式。 例如,Ruby允许你做类似的事情:

time_spec = /noon|midnight|\d{1,2}/
sep = /-|to/
match = /#{time_spec}\s*#{sep}\s*#{time_spec}/

但是,因为这似乎会在扩展时变得更加复杂,为什么不创建某种解析器(使用flex / yacc?),它将比正则表达式保持更好? 当你开始支持一系列输入时,如1 pm/1p/13:00/13正则表达式开始创建更多问题然后解决方案。

答案 2 :(得分:0)

看起来你可以根据"-""to"进行拆分。

^(.+) ?(-|to) ?(.+)$

这将捕获第一组中的开始时间和第三组中的结束时间。如果您需要更具体的语法,则必须指定要使用的正则表达式的哪个版本。