1

Regexp#match(str, index)给了我index字符串之后的第一个匹配项,这对于从左到右遍历每个匹配项非常有用。但是我怎样才能找到给定索引之前的最后一个匹配项?给出最后一场比赛的索引,但如果我想要完整的比赛数据怎么办?String#rindex

例子:

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

...应该屈服...

#<MatchData "zoo">
4

3 回答 3

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"
于 2012-10-21T01:22:32.040 回答
0

这是一个猴子补丁解决方案:

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">
于 2012-10-21T02:41:54.120 回答
-1

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

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

如果它所代表的语言确实是常规的,则反转正则表达式很简单。贪婪或缺乏贪婪可能会导致您必须考虑的极端情况。

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

于 2012-10-21T01:28:02.910 回答