sicpばかりしてたら、rubyのコードが書きたくなった。
「def esub! args new_syms」と書いたときのエラーに素で驚いた。
今回書いたコード
引数をとって一気にgsub!。*1
class String def esub! args, new_syms = nil if new_syms.nil? #argsがハッシュのとき regexps = args.keys.map {|e| Regexp.new e} new_syms = args.values else #argsが配列のとき regexps = args.map {|e| Regexp.new e} end regexps.inject(self) do |orig, change| # p orig edit_sym = new_syms.shift orig.gsub!(change) {edit_sym} end end def esub args, new_syms=nil dup.esub! args, new_syms end end def outputs target puts "元の文字列: #{target}" puts "結果 : #{yield(target)}" puts "置換後の文字列: #{target}" puts end x="aiueo" outputs(x) {|e| e.esub(%w{a i u e o}, %w{1 2 3 4 5})} puts "===============" outputs(x) {|e| e.esub!(%w{a i u e o}, %w{1 2 3 4 5})} #hashも使えます $KCODE='utf8' y="今日は疲れました。ふとんでゆっくり寝たいです。" h={"今日は" => "明日もきっと", "ました" => "ます。"} outputs(y) {|e| e.esub(h)} puts "===============" #正規表現も使えます。 z= "a b cde 55 4 3 2" outputs(z) {|e| e.esub(%w{\s+ \d+}, %w{(・_・), 44})}
結果
元の文字列: aiueo 結果 : 12345 置換後の文字列: aiueo =============== 元の文字列: aiueo 結果 : 12345 置換後の文字列: 12345 元の文字列: 今日は疲れました。ふとんでゆっくり寝たいです。 結果 : 明日もきっと疲れます。。ふとんでゆっくり寝たいです。 置換後の文字列: 今日は疲れました。ふとんでゆっくり寝たいです。 =============== 元の文字列: a b cde 55 4 3 2 結果 : a(・_・),b(・_・),cde(・_・),44(・_・),44(・_・),44(・_・),44 置換後の文字列: a b cde 55 4 3 2
*1:respond_to? で分岐した方が良かったかもしれない