如何使用正则表达式和反向引用编写Ruby switch语句(case ... when)?

时间:2011-07-23 22:13:25

标签: ruby regex switch-statement

我知道我可以编写一个Ruby case语句来检查正则表达式的匹配。 但是,我想在return语句中使用匹配数据。像这样的半伪代码:

foo = "10/10/2011"

case foo
    when /^([0-9][0-9])/
        print "the month is #{match[1]}"
    else
        print "something else"
end

我怎样才能做到这一点?

谢谢!


请注意:我理解我不会像上面那样对一个简单的情况使用switch语句,但这只是一个例子。实际上,我想要实现的是许多潜在的正则表达式匹配日期,可以用各种方式编写,然后相应地用Ruby的Date类解析它。

2 个答案:

答案 0 :(得分:142)

对最新正则表达式匹配组的引用始终存储在pseudo variables $1$9中:

case foo
when /^([0-9][0-9])/
    print "the month is #{$1}"
else
    print "something else"
end

您还可以使用$LAST_MATCH_INFO伪变量来获取整个MatchData对象。这在使用命名捕获时非常有用:

case foo
when /^(?<number>[0-9][0-9])/
    print "the month is #{$LAST_MATCH_INFO['number']}"
else
    print "something else"
end

答案 1 :(得分:6)

这是一种替代方法,可以获得相同的结果但不使用开关。如果将正则表达式放在数组中,则可以执行以下操作:

res = [ /pat1/, /pat2/, ... ]
m   = nil
res.find { |re| m = foo.match(re) }
# Do what you will with `m` now.

在块之外声明m允许它在块find完成后仍然可用,并且只要块返回真值就会停止find,这样你就可以得到与交换机相同的快捷行为。如果你需要它,你会得到完整的MatchData(也许你想在你的正则表达式中使用命名的捕获组)并且很好地将你的正则表达式与你的搜索逻辑分开(这可能会或者可能不会产生更清晰的代码),你甚至可以从配置文件加载你的正则表达式或在运行时选择你想要的那组。