Ruby String#scan equivalent to return MatchData

半世苍凉 提交于 2019-12-03 17:01:00

问题


As basically stated in the question title, is there a method on Ruby strings that is the equivalent to String#Scan but instead of returning just a list of each match, it would return an array of MatchDatas? For example:

# Matches a set of characters between underscore pairs
"foo _bar_ _baz_ hashbang".some_method(/_[^_]+_/) #=> [#&ltMatchData "_bar_"&rt, &ltMatchData "_baz_"&rt]

Or any way I could get the same or similar result would be good. I would like to do this to find the positions and extents of "strings" within Ruby strings, e.g. "goodbye and "world" inside "'goodbye' cruel 'world'".


回答1:


You could easily build your own by exploiting MatchData#end and the pos parameter of String#match. Something like this:

def matches(s, re)
  start_at = 0
  matches  = [ ]
  while(m = s.match(re, start_at))
    matches.push(m)
    start_at = m.end(0)
  end
  matches
end

And then:

>> matches("foo _bar_ _baz_ hashbang", /_[^_]+_/)
=> [#<MatchData "_bar_">, #<MatchData "_baz_">]
>> matches("_a_b_c_", /_[^_]+_/)
=> [#<MatchData "_a_">, #<MatchData "_c_">]
>> matches("_a_b_c_", /_([^_]+)_/)
=> [#<MatchData "_a_" 1:"a">, #<MatchData "_c_" 1:"c">]
>> matches("pancakes", /_[^_]+_/)
=> []

You could monkey patch that into String if you really wanted to.




回答2:


memo = []
"foo _bar_ _baz_ hashbang".scan(/_[^_]+_/) { memo << Regexp.last_match }
 => "foo _bar_ _baz_ hashbang"
memo
 => [#<MatchData "_bar_">, #<MatchData "_baz_">]



回答3:


If you don't need to get MatchDatas back, here's a way using StringScanner.

require 'strscan'

rxp = /_[^_]+_/
scanner = StringScanner.new "foo _barrrr_ _baz_ hashbang"
match_infos = []
until scanner.eos?
  scanner.scan_until rxp
  if scanner.matched?
    match_infos << {
      pos: scanner.pre_match.size,
      length: scanner.matched_size,
      match: scanner.matched
    }
  else
    break
  end
end

p match_infos
# [{:pos=>4, :length=>8, :match=>"_barrrr_"}, {:pos=>13, :length=>5, :match=>"_baz_"}]


来源:https://stackoverflow.com/questions/9528035/ruby-stringscan-equivalent-to-return-matchdata

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!