如何获取Ruby中正则表达式字符串中最后一个匹配的完整匹配数据?

时间:2012-10-21 00:37:08

标签: ruby regex

Regexp#match(str, index)为我提供了index之后的第一场比赛,非常适合从左到右迭代每场比赛。但是如何在给定索引之前找到 last 匹配String#rindex给出了最后一个匹配的索引,但是如果我想要完整匹配数据呢?

示例:

/.oo/.rmatch("foo boo zoo")

......应该屈服......

#<MatchData "zoo">

3 个答案:

答案 0 :(得分:2)

您可以通过对字符串进行子串输接来限制正则表达式可以匹配的字符串的距离。

irb> /.oo/.match("foo boo zoo"[0..-3])
=> #<MatchData "foo">
irb> /.oo/.match("foo boo zoo"[0..-3],3)
=> #<MatchData "boo">
irb> /.oo/.match("foo boo zoo"[3..-3]) # can also express the start with slice
=> #<MatchData "boo">
irb> /.oo/.match("foo boo zoo"[0..-3],5)
=> nil

String#scan将重复应用正则表达式返回所有匹配的数组,您只需从中选择最后一个匹配。

module RegexpHelper
  def rmatch str, rlimit = -1
    str[0..rlimit].scan(self).last
  end
end

Regexp.send :include, RegexpHelper

/.oo/.rmatch 'foo boo moo'     # => "moo"
/.oo/.rmatch 'foo boo moo', -3 # => "boo"
/.oo/.rmatch 'foo boo moo', 4  # => "foo"

答案 1 :(得分:0)

这是一个monkeypatch解决方案:

class Regexp
  def rmatch str, offset = str.length
    last_match = match str
    while last_match && last_match.offset(0).last < offset
      break unless m = match(str, last_match.offset(0).last)
      last_match = m
    end
    last_match
  end
end

p /.oo/.rmatch("foo boo zoo")
#<MatchData "zoo">

答案 2 :(得分:-1)

您可以反转字符串,反转正则表达式,并使用length(str) - index作为起始点。

1.9.3p194 :010 > /oo./.match("foo boo zoo".reverse)[0].reverse
=> "zoo" 

如果它所代表的语言非常规则,那么反转正则表达式很简单。贪婪或缺乏贪婪可能会导致你需要思考的边缘情况。

如果正则表达式有一个Kleene星,我相信这是完成工作的唯一方法,除非你建立自己的反向正则表达式匹配器,这是一个大项目。