argius note

プログラミング関連

正規表現で文字列置換えしよう

世間では海豚*1暴れ馬の話題に沸いているようですが、自分はまだ蟷螂と戯れています。
さて、Perl正規表現による文字列置換をJavaでやるには、1.3まではJakartaとかのライブラリ(OROだっけか)使ったりだったが、1.4から標準ライブラリ(java.util.regex)に搭載されました。APIドキュメントを見ながらどうやるのか調べていたら、Matcher.appendReplacementメソッドのサンプルコードがなんか変だ。日本語版は古いの(1.4.0)しかないから仕方が無いが、ということで本家(1.4.2)を見たら、ちゃんと直っていた。
で、Javaのやり方が分かったので、PerlJavaで同じような処理を書いてみる。

#!/usr/bin/perl
# replace.pl
$a = shift; # pattern
$b = shift; # replace
while (<>) {
    # eval for $n
    eval "s/$a/$b/g";
    print;
}

追記:Java版はちょっとひどいので訂正しましたhttp://d.hatena.ne.jp/argius/20080512/1210599767

// test/Main.java
public static void main(String[] args) throws IOException {
    String a = args[0]; // pattern
    String b = args[1]; // replace
    Pattern pattern = Pattern.compile(a);
    BufferedReader bufferedReader
                = new BufferedReader(new InputStreamReader(System.in));
    try {
        for (String line; (line = bufferedReader.readLine()) != null;) {
            Matcher matcher = pattern.matcher(line);
            StringBuffer buffer = new StringBuffer();
            while (matcher.find()) {
                matcher.appendReplacement(buffer, b);
            }
            matcher.appendTail(buffer);
            System.out.println(buffer);
        }
    } finally {
        bufferedReader.close();
    }
}

実行は以下のとおり。

$ cat data.txt
east west
right left
1280 0
$ cat data.txt | perl a.pl '(.+) (.+)' '$2 $1'
west east
left right
0 1280
$ cat data.txt | java test.Main '(.+) (.+)' '$2 $1'
west east
left right
0 1280
$

*1:DolphinはJava7のコードネームだった。ただし、コードネームを間違えたのではなく、バージョンを間違えていた。