[Java]正規表現メモ-コールバック的な置換とか

カンタンな正規表現

Matcher matcher = Pattern.compile("[0-9]{3}").matcher("123-456-789");
// find で 次のマッチを検索する
// マッチしなければ false を返す。
String out = "";
while( matcher.find() ) {
  out += matcher.start() + "-" + matcher.end() + "=>" + matcher.group(0) + "\n";
}
System.out.println(out);

結果

0-3=>123
4-7=>456
8-11=>789

マッチした部分をメソッドで処理して置換

Javascript だと callback な 置換処理(? どう呼べばいいのかわからん)は超簡単なんだけど…Java だと随分とメンドクサイことになってしまう…

package jp.fernweh;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReplaceCallback {

  public static void main(String[] args) {
    String str = "-123-456-789!!!";
    Matcher matcher = Pattern.compile("\\d{3}").matcher(str);
    StringBuffer buffer = new StringBuffer();
    while (matcher.find()) {
      // マッチした部分を置き換えて buffer に結合
      matcher.appendReplacement(buffer, replaceMethod(matcher));
    }
    matcher.appendTail(buffer); // 末尾の !!! を結合
    System.out.println(buffer.toString());
  }

  private static String replaceMethod(Matcher matcher) {
    // ここで自由に処理できる。
    Integer num = Integer.parseInt(matcher.group());
    num *= 1000;
    return num.toString();
  }
}

結果

-123000-456000-789000

Java だとクロージャないから不便っすな… Groovy ならクロージャでこういう処理は楽に書けるっぽいけど触ったことがない

使用するなら下記リンクのように置換用のクラスを作成すべきかな。

エスケープでハマる

Pattern compile = Pattern.compile("[[\\]]");

ちょ、なんでこれで例外飛ぶの…

と思ったらどうやら Java では [] 内の [ もエスケープしないとダメらしい…

Java では [\\[\\]] とするのが正しい。

四角括弧 内の &&

これは Java 特有かな?

Pattern compile = Pattern.compile("[^abc&&a-z]");

四角括弧内で && を使用すると複合条件の文字クラスを使用出来る。

正規表現が関わるメソッドのメモ

  • String#replaceAll(String regx, String rep), String#split(String regx) は正規表現を使用している。
  • Scanner クラスでも正規表現を使える。
Share