有没有办法在 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
那可能吗?