opamp_sando's blog

クソザコが割りと適当なことを書くためにある備忘録です。あとたまに普通の日記も書きます

Rubyで文字列中の括弧を削除する

例えば"aaa(bbb)ccc(ddd)eee"という文字列があったら、"aaaccceee"というふうに文字列を取り出す。

※コメントやツイッターでもっと簡単な方法を教えていただいたので下の長い奴より記事末尾の追記のほうを参照してもらったほうがいいかもです。

str = "aaa(bbb)ccc(ddd)eee" #対象文字列

one = str
two = String.new

until one == two
    two = one
    one = one.sub(/\(.*?\)/,"")
end

puts "original -> #{str}"
puts "remove parentheses -> #{one}" #-> aaaccceee

ということでできた。
Rubyistならもっと短く書けるかもしれないけど今のおいらにはこれが限界だ。
なんかもっと便利なメソッドとか手法があるかもしれないけどとりあえずこんなものしか思いつかなかった。

で、これを利用してファイルから括弧部分を削除するプログラムを書いてみた

#!/bin/env ruby
#-*- encoding:utf-8 -*-

exit 1 unless File.directory?(ARGV[0])
TARGET = ARGV[0]

def chname(dir)
        Dir::entries(dir).each do |e|
                next if e == "." or e == ".."
                next if e =~ /^\./
                chname(dir + File::SEPARATOR + e) if File.directory?(dir + File::SEPARATOR + e)
                one = e
                two = String.new
                until one == two
                        two = one
                        one = one.sub(/\(.*?\)/,"")
                end
                File::rename(dir + File::SEPARATOR + e,dir + File::SEPARATOR + one)
                puts "[RENAMED]FROM:#{dir + File::SEPARATOR + e} TO:#{dir + File::SEPARATOR + one}"
        end
end

puts "=> TARGET DIRECOTRY IS #{TARGET}"
chname(TARGET)
puts "FINISHED"

コマンドライン引数(第一引数)で渡したディレクトリ内のファイルの括弧を取り払うスクリプト。


ちなみにsubの正規表現部分は".*"にするとaa(bb)cc(dd)eeとあるのを(bbからdd)までで1つと認識するみたいでaaeeという結果になりccが消える。調べてみたら"*"はできるだけ長くマッチしようとする性質があるようだ.
なので、できるだけ短くマッチする"*?"を使う。


追記:
ブログのコメントやツイッターで他にもいくつか方法を教えてもらったのでそちらを使ったほうがよさそうです。どちらも1行程度ですみます。

str = "aa(bb)cc(dd)ee"

str.split(/\(.*?\)/).join #=> aaccee

こちらの方法はツイッターで教えていただいた方法で、正規表現にマッチした部分で切って配列を生成し、それをjoinでつなげる方法ですね。


続いてコメントで教えていただいた方法ですが、どうやら見落としていたようでgsubなるメソッドがあるようです。

str = "aa(bb)cc(dd)ee"

str.gsub(/\(.*?\)/,"") #=> aaccee

こちらは見つかったものすべてを置換します。

Firefox ブラウザ無料ダウンロード