Feature #5606
closedString#each_match(regexp)
Description
文字列上の正規表現に一致する場所のoffsetを順に処理できるような
イテレータが欲しかったのですが、
ざっと検索すると1996年
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/1206
の昔から話はあり、
http://stackoverflow.com/questions/6804557/how-do-i-get-the-match-data-for-all-occurrences-of-a-ruby-regular-expression-in
全くないという事はなくて、それなりに需要がありそうです。
class String
def each_match(pattern, offset=0)
while(m = self.match(pattern, offset))
offset = m.begin(0)+1
yield m
end
end
end
いかがしょうか?
対称にはRegexp#each_matchもですが、、
Updated by naruse (Yui NARUSE) about 13 years ago
String#scan ではダメな理由を、ユースケースを添えて示す必要があると思います。
Updated by tomoakin (Tomoaki Nishiyama) about 13 years ago
長い配列中のモチーフの存在位置のリストを作りたいので、位置(offset)が必要です。
String#scan ではダメかというと
longstring.scan(regex) do |matchstr|
m=Regexp.last_match
...
puts "#{m.begin(0)}-#{m.end(0)-1} some other info"
end
でとれば確かにとれるらしいけど、いかにもトリッキーな気がしますので、直接的に
longstring.each_match(regex) do |m|
...
puts "#{m.begin(0)}-#{m.end(0)-1} some other info"
end
と書ける方がうれしいです。
Updated by mame (Yusuke Endoh) over 12 years ago
- Status changed from Open to Feedback
遠藤です。
2011年11月10日17:19 Tomoaki Nishiyama tomoakin@staff.kanazawa-u.ac.jp:
String#scan ではダメかというと
longstring.scan(regex) do |matchstr|
m=Regexp.last_match
...
puts "#{m.begin(0)}-#{m.end(0)-1} some other info"
endでとれば確かにとれるらしいけど、いかにもトリッキーな気がしますので、
$~ を使うのが普通です。
longstring.scan(regex) do
...
puts "#{$~.begin(0)}-#{$~.end(0)-1} some other info"
end
「いかにもトリッキー」というほどトリッキーとは思いませんが、
気持ちはわかります。しかし、String#scan と String#gsub の
ブロックパラメータをそろえろ! (#546) という話に関係しなく
もなく、話が進みにくいタイプの提案だと思いました。
機会を見つけてまつもとさんに直談判することをお勧めします。
いずれにせよ、ユースケースを示してください。
ところで、参照実装で
offset = m.end(0)
でなく
offset = m.begin(0)+1
になってるのは意図的でしょうか。
--
Yusuke Endoh mame@tsg.ne.jp
Updated by mame (Yusuke Endoh) almost 12 years ago
- Target version set to 2.6
Updated by shyouhei (Shyouhei Urabe) about 6 years ago
- Related to Feature #12745: String#(g)sub(!) should pass a MatchData to the block, not a String added