【问题标题】:Ruby Regex: How to match (named) groups inside square brackets?Ruby Regex:如何在方括号内匹配(命名)组?
【发布时间】: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 不做任何自动解析,它需要一个格式字符串(这基本上是我在这里构建的),它也在 DateDateTime 对象上,而不是Time 对象。不幸的是,Ruby 的 Date.parse 不是很健壮,不像 Python 的 dateutil.parser.parse,这太糟糕了,因为我通常更喜欢 Ruby 而不是 Python。转义括号中的+- 是个好主意,但我只是尝试过,结果相同。我想这并不奇怪,因为我没有在原始的正则表达式中转义它们,并且在那里运行良好。

标签: ruby regex optional capture brackets


【解决方案1】:

方括号用于“这些字符中的任何一个”——这不是你需要的。模式级交替通过 | 运算符完成:(hello|goodbye) world 将匹配 hello worldgoodbye world

(?<offset>Z|[+-]\d{2}:\d{2})?

不过,特别是要解析日期时间,我建议更喜欢 DateTime.parse(加上 to_time,如果您需要 Time 实例)。如果这不够灵活,请考虑使用 chronic gem。

【讨论】:

  • Date#parseDateTime#parse 并不总是给出预期的结果:Date.parse "It appears that Theresa May is not especially fond of Mr. Trump" #=&gt; #&lt;Date: 2018-05-01 ((2458240j,0s,0n),+0s,2299161j)&gt;
  • @matthewd 这正是我所需要的,谢谢!这就像一个魅力!
猜你喜欢
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
相关资源
最近更新 更多