Regexp#match(str, index)
给了我index
字符串之后的第一个匹配项,这对于从左到右遍历每个匹配项非常有用。但是我怎样才能找到给定索引之前的最后一个匹配项?给出最后一场比赛的索引,但如果我想要完整的比赛数据怎么办?String#rindex
例子:
/.oo/.rmatch("foo boo zoo")
...应该屈服...
#<MatchData "zoo">
Regexp#match(str, index)
给了我index
字符串之后的第一个匹配项,这对于从左到右遍历每个匹配项非常有用。但是我怎样才能找到给定索引之前的最后一个匹配项?给出最后一场比赛的索引,但如果我想要完整的比赛数据怎么办?String#rindex
例子:
/.oo/.rmatch("foo boo zoo")
...应该屈服...
#<MatchData "zoo">
您可以通过对字符串进行子字符串化来限制正则表达式可以匹配的字符串的深度。
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"
这是一个猴子补丁解决方案:
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">
您可以反转字符串、反转正则表达式并用作length(str) - index
起点。
1.9.3p194 :010 > /oo./.match("foo boo zoo".reverse)[0].reverse
=> "zoo"
如果它所代表的语言确实是常规的,则反转正则表达式很简单。贪婪或缺乏贪婪可能会导致您必须考虑的极端情况。
如果正则表达式有一个 Kleene 星,我相信这是完成工作的唯一方法,除非您构建自己的反向正则表达式匹配器,这是一个大项目。