具有命名捕获支持的 Ruby 正则表达式匹配枚举器

Posted

技术标签:

【中文标题】具有命名捕获支持的 Ruby 正则表达式匹配枚举器【英文标题】:Ruby regular expression matching enumerator with named capture support 【发布时间】:2013-11-04 22:59:16 【问题描述】:

考虑这样一个字符串来提取时间信息:

str = "Sun rises at 6:23 am & sets at 5:45 pm; Moon comes up by 7:20 pm and goes down by 3:45 am"

我希望有一个像 scan 这样的枚举器,但它可以让我获得 MatchData 对象,而不是扫描中可用的数组。

例如,我可以写:

str.scan( /(?<time>\d:\d2) (?<meridiem>am|pm)/ ) |arr| p arr

得到:

["6:23", "am"] ["5:45", "pm"] ["7:20", "pm"] ["3:45", "am"]

但是,我想知道是否有这样的事情:

str.match_all( /(?<time>\d:\d2) (?<meridiem>am|pm)/ ) |md| p md

得到:

#<MatchData "6:23 am" time:"6:23" meridiem:"am"> #<MatchData "5:45 pm" time:"5:45" meridiem:"pm"> #<MatchData "7:20 pm" time:"7:20" meridiem:"pm"> #<MatchData "3:45 am" time:"3:45" meridiem:"am">

在previous question 中看到了答案,但我觉得这是一个不雅的解决方案。因此,请检查一下,以防在发布答案后的过去几年中情况发生了变化。

【问题讨论】:

对你提到的问题的接受答案对我来说似乎很简短而且很优雅。你可以在此基础上实现这个match_all 我同意@Guilherme 的观点,但考虑您的问题并查看较早的答案对我很有帮助。 对链接问题的接受答案与我能想到的一样优雅。如果您对此还不满意,请自己想一个更优雅的答案。考虑到您的高标准,您应该可以自己完成。 谢谢大家;可能你是对的!我以某种方式假设应该存在这样的match_all 方法,假设要求相当普遍。我必须为引用的答案使用“不雅”一词而道歉;我只是在寻找一种相当直接的方法。 【参考方案1】:

与您已经看到的答案非常相似,但略有不同。

str = "Sun rises at 6:23 am & sets at 5:45 pm; Moon comes up by 7:20 pm ..."
str.gsub(/(?<time>\d:\d2) (?<meridiem>am|pm)/).map Regexp.last_match  

#=> [#<MatchData "6:23 am" time:"6:23" meridiem:"am">, #<MatchData "5:45 pm" ...

【讨论】:

我正在考虑类似的解决方案,但我不知道Regexp.last_match 存在。但是在考虑它的范围时,以某种方式从那里捕获 MatchData 对我来说似乎有问题。 真的希望像 match_all 这样的东西存在!令人难以置信的是为什么它没有。

以上是关于具有命名捕获支持的 Ruby 正则表达式匹配枚举器的主要内容,如果未能解决你的问题,请参考以下文章

java 匹配正则表达式并捕获命名模式

正则表达式进阶

正则表达式中的命名捕获组

Ruby知识概要

具有多个捕获组的 R 中的正则表达式组捕获

Java 正则表达式之捕获组