正規表現での置換

ソースコード中のある文字列を一括置換したいということが、たまにあると思います。
特定の単語1語だけなら、IDEの機能をそのまま使えばいいだけですが、
ちょっと複雑なときもあります。
例えば、クラスに定義している定数をプロパティファイル化したいなど。


【定数定義】

public class HogeConst {

    public static final String MESSAGE_1 = "メッセージ1";
    public static final String MESSAGE_2 = "メッセージ2";
    public static final String MESSAGE_3 = "メッセージ3";

}

【使用例】

    private String fuga = HogeConst.MESSAGE_1; 

こんなのを
【プロパティファイル】

MESSAGE_1 = メッセージ1
MESSAGE_2 = メッセージ2
MESSAGE_3 = メッセージ3

【使用例】

    private Properties properties = null;
    properties.load(ResourceUtil.getResourceAsStreamNoException("message.properties");
    private String fuga = properties.get("MESSAGE_1"); 

こんな感じにしたい。


プロパティファイルの作成方法等は省略しますが、
ここでは、プロパティから指定されたキーの値を取得する以下のようなメソッドを作ったとして進めます。

public class MessageUtil {
    public static String get(String key) {
        …
        return properties.get(key);
    }
}

ちなみに、プロパティのキーは定数名をそのまま使うこととします。


そうすると、

    private String fuga = HogeConst.MESSAGE_1; 

    private String fuga = MessageUtil.get("MESSAGE_1"); 

こんな風にしてやればいいです。

  • 「HogeConst.」を「MessageUtil.get("」に置換
  • 定数名の後ろに「"」を付加


Ruby正規表現が強力だとどこかで聞いた覚えがあるので、
一括置換するコードをRubyで書いてみました。

hoge = " private String fuga = HogeConst.XYZ;"
fuga = hoge.scan(/(LocaleConst.)([A-Z]+)/)
# => [["HogeConst.", "XYZ"]]
hoge.sub(/HogeConst.[A-Z]+/, 'MessageUtil.get("' + fuga[0][1] + '")')
# => " private String fuga = MessageUtil.get(\"XYZ\");"

とりあえずここまで。

あとは、

  1. ソースファイルを読み込んで置換する
  2. カレントディレクトリからサブディレクトリのファイルまで全てを処理するように再帰構造にする
  3. 置換したファイルにはMessageUtilをimportしてやる

くらいでしょうか。

まだまだでした。。。orz