【发布时间】:2019-01-04 00:38:03
【问题描述】:
我正在尝试用 Ruby 编写一个解析各种日期/时间格式的正则表达式。整个正则表达式如下所示:
/^(?<year>\d{4})\-(?<month>\d{2})\-(?<day>\d{2})(T(?<hour>\d{2})(:(?<minute>\d{2})(:(?<second>\d{2}(\.\d{1,3})?))?)?)?(?<offset>[+-]\d{2}:\d{2})?$/
我正在使用命名组,这样我就可以使用“年”、“月”、“日”等简单名称从匹配对象中提取匹配的部分。这个正则表达式工作正常,但让我们关注结尾处的“偏移量”:
(?<offset>[+-]\d{2}:\d{2})?
问题是我试图在字符串末尾添加解释“Z”以表示 UTC 时间(又名祖鲁时间)的能力。这个“Z”应该与偏移量互斥。以下是我尝试过的一些方法:
(?<offset>[Z([+-]\d{2}:\d{2})])?
(?<offset>[(Z)([+-]\d{2}:\d{2})])?
[(?<zulu>Z)(?<offset>[+-]\d{2}:\d{2})]?
这些都不起作用。在前两种情况下,它可以解释以“Z”结尾的日期字符串,但不能再解释以“-07:00”等实际偏移量结尾的日期字符串。在第三种情况下,匹配对象中完全缺少命名组“zulu”和“offset”。
我认为这个问题是因为我尝试使用方括号来表示[(ThisGroup)(OrThisGroup)]?,但我认为正则表达式引擎不喜欢在方括号内包含组。如何告诉正则表达式引擎允许并捕获“A 组或 B 组,或两者都没有,但不能同时捕获”?
【问题讨论】:
-
为了清楚起见,您能否发布一些您想要与预期结果匹配的示例字符串?此外,没有任何内置时间解析器足以满足您的任务,例如
Time.strptime? -
我正要问同样的问题。为什么不使用
Date.parse? -
strptime不做任何自动解析,它需要一个格式字符串(这基本上是我在这里构建的),它也在Date和DateTime对象上,而不是Time对象。不幸的是,Ruby 的Date.parse不是很健壮,不像 Python 的dateutil.parser.parse,这太糟糕了,因为我通常更喜欢 Ruby 而不是 Python。转义括号中的+和-是个好主意,但我只是尝试过,结果相同。我想这并不奇怪,因为我没有在原始的正则表达式中转义它们,并且在那里运行良好。
标签: ruby regex optional capture brackets