Ruby 正则表达式:如何匹配方括号内的(命名的)组?
Ruby Regex: How to match (named) groups inside square brackets?
我正在尝试用 Ruby 编写一个正则表达式,它将解析各种 date/time 格式。整个正则表达式如下所示:
/^(?<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})?$/
我正在使用命名组,这样我就可以使用 "year"、"month"、"day" 等简单名称从匹配对象中提取匹配部分。这个正则表达式工作正常,但让我们关注最后的 "offset":
(?<offset>[+-]\d{2}:\d{2})?
问题是我试图添加解释字符串末尾的 "Z" 的能力,以表示 UTC 时间(又名祖鲁时间)。这个"Z"应该和offset是互斥的。以下是我尝试过的一些方法:
(?<offset>[Z([+-]\d{2}:\d{2})])?
(?<offset>[(Z)([+-]\d{2}:\d{2})])?
[(?<zulu>Z)(?<offset>[+-]\d{2}:\d{2})]?
None 这些作品。在前两种情况下,它可以解释以 "Z" 结尾的日期字符串,但它不能再解释以实际偏移量结尾的日期字符串,如“-07:00”。在第三种情况下,命名组 "zulu" 和 "offset" 完全没有出现在匹配对象中。
我认为这个问题是因为我正在尝试使用方括号来表示 [(ThisGroup)(OrThisGroup)]?
但我认为正则表达式引擎不喜欢在方括号内包含组。如何告诉正则表达式引擎允许并捕获 "group A or group B or neither, but not both"?
方括号用于 "exactly one of any of these characters"——这不是您在这里需要的。模式级交替是通过 |
运算符完成的:(hello|goodbye) world
将匹配 hello world
或 goodbye world
.
(?<offset>Z|[+-]\d{2}:\d{2})?
不过,特别是为了解析日期时间,我建议首选 DateTime.parse
(加上 to_time
,如果您需要时间实例)。如果这不够灵活,请考虑 chronic gem.
我正在尝试用 Ruby 编写一个正则表达式,它将解析各种 date/time 格式。整个正则表达式如下所示:
/^(?<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})?$/
我正在使用命名组,这样我就可以使用 "year"、"month"、"day" 等简单名称从匹配对象中提取匹配部分。这个正则表达式工作正常,但让我们关注最后的 "offset":
(?<offset>[+-]\d{2}:\d{2})?
问题是我试图添加解释字符串末尾的 "Z" 的能力,以表示 UTC 时间(又名祖鲁时间)。这个"Z"应该和offset是互斥的。以下是我尝试过的一些方法:
(?<offset>[Z([+-]\d{2}:\d{2})])?
(?<offset>[(Z)([+-]\d{2}:\d{2})])?
[(?<zulu>Z)(?<offset>[+-]\d{2}:\d{2})]?
None 这些作品。在前两种情况下,它可以解释以 "Z" 结尾的日期字符串,但它不能再解释以实际偏移量结尾的日期字符串,如“-07:00”。在第三种情况下,命名组 "zulu" 和 "offset" 完全没有出现在匹配对象中。
我认为这个问题是因为我正在尝试使用方括号来表示 [(ThisGroup)(OrThisGroup)]?
但我认为正则表达式引擎不喜欢在方括号内包含组。如何告诉正则表达式引擎允许并捕获 "group A or group B or neither, but not both"?
方括号用于 "exactly one of any of these characters"——这不是您在这里需要的。模式级交替是通过 |
运算符完成的:(hello|goodbye) world
将匹配 hello world
或 goodbye world
.
(?<offset>Z|[+-]\d{2}:\d{2})?
不过,特别是为了解析日期时间,我建议首选 DateTime.parse
(加上 to_time
,如果您需要时间实例)。如果这不够灵活,请考虑 chronic gem.