Rubyでグループ名によるグループ化された正規表現を使用して置換を実行する方法はありますか?
これは私がこれまでに得たものです (ただし、かなり一般的な状況では役に立たない、いくつかの貴重なコンテキストが欠けていることがわかります):
class String
def scan_in_groups( regexp )
raise ArgumentError, 'Regexp does not contain any names.' if regexp.names.empty?
captures = regexp.names.inject( {} ){ |h, n| h[n] = []; h }
scan( regexp ).each do |match|
captures.keys.zip( match ).each do |group, gmatch|
next if !gmatch
captures[group] << gmatch
end
end
captures.reject { |_, v| v.empty? }
end
def sub_in_groups( regexp, group_hash )
dup.sub_in_groups!( regexp, group_hash )
end
def sub_in_groups!( regexp, group_hash )
scan_in_groups( regexp ).each do |name, value|
next if !group_hash[name]
sub!( value.first, group_hash[name] )
end
self
end
end
regexp = /
\/(?<category>\w+) # matches category type
\/ # path separator
(?<book-id>\d+) # matches book ID numbers
\/ # path separator
.* # irrelevant
\/ # path separator
chapter-(?<chapter-id>\d+) # matches chapter ID numbers
\/ # path separator
stuff(?<stuff-id>\d+) # matches stuff ID numbers
/x
path = '/book/12/blahahaha/test/chapter-3/stuff4/12'
p path.scan_in_groups( regexp )
#=> {"category"=>["book"], "book-id"=>["12"], "chapter-id"=>["3"], "stuff-id"=>["4"]}
update = {
'category' => 'new-category',
'book-id' => 'new-book-id',
'chapter-id' => 'new-chapter-id',
'stuff-id' => '-new-stuff-id'
}
p path.sub_in_groups( regexp, update )
#=> "/new-category/new-book-id/blahahaha/test/chapter-new-chapter-id/stuff-new-stuff-id/12"
p '/12/book/12/blahahaha/test/chapter-3/stuff4/12'.sub_in_groups( regexp, update )
#=> /new-book-id/new-category/12/blahahaha/test/chapter-new-chapter-id/stuff-new-stuff-id/12
私が必要としているのは、正規表現の一致のコンテキストを保持し、最終結果が次のようになるようにそれらを慎重に置き換えるソリューションです。
#=> /12/new-category/new-book-id/blahahaha/test/chapter-new-chapter-id/stuff-new-stuff-id/12
それは可能ですか?