コロッと忘れていたようなので、メモ。
java.util.regex.Matcher#replaceAllやreplaceFirst、String#replaceAllやreplaceFirstで$を使った後方参照が使えます。
普段あんまりJavaで正規表現による置換を多用しないのと、Perlに頼り切ってることが多かったですからねぇ。あとはMatcher#groupを使ってたような…。
こんな感じで、まずはjava.util.regexパッケージを使用する場合。
String target = "Hello 1234 World 5678"; Pattern p = Pattern.compile("[^\\d]+ (\\d+) [^\\d]+ (\\d+)"); Matcher m = p.matcher(target); System.out.println(m.replaceAll("Numbers = [$1 $2], origin = [$0]")); // => Numbers = [1234 5678], origin = [Hello 1234 World 5678]
$1、$2…と後方参照が可能です。$0を指定した場合は、マッチした文字列全体が取れます。
Stringクラスだけでも大丈夫。
System.out.println(target.replaceAll("[^\\d]+ (\\d+) [^\\d]+ (\\d+)", "Numbers = [$1 $2], origin = [$0]")); // => Numbers = [1234 5678], origin = [Hello 1234 World 5678]
Javaでいけるなら、GroovyでもOK。
def target = 'Hello 1234 World 5678' println(target.replaceAll(/[^\d]+ (\d+) [^\d]+ (\d+)/, 'Numbers = [$1 $2], origin = [$0]')) // => Numbers = [1234 5678], origin = [Hello 1234 World 5678] def p = ~/[^\d]+ (\d+) [^\d]+ (\d+)/ def m = (target =~ p) println(m.replaceAll('Numbers = [$1 $2], origin = [$0]')) // => Numbers = [1234 5678], origin = [Hello 1234 World 5678]
Groovyの場合は、GStringと混ざらないようにシングルクォートで囲むべしって感じですか。
Scalaのscala.util.matching.Regexでもいけます。
val target = "Hello 1234 World 5678" val regex = """[^\d]+ (\d+) [^\d]+ (\d+)""".r println(regex.replaceAllIn(target, "Numbers = [$1 $2], origin = [$0]")) // => Numbers = [1234 5678], origin = [Hello 1234 World 5678]
たまには使ってみましょうっと。