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

これが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">
于 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 に答える