Java の正規表現クラスの仕様

必ずマッチするはずなのに

正規表現のパターンは /\.txt$/ で、マッチさせる文字列は testfile.txt とした場合、必ずマッチするはずだ。
しかし、正規表現の結果は条件分岐で false (マッチしていない) と判定されることに、かなりイライラした。

メソッドの仕様が異なっていた

最初使っていたメソッドは、java.util.regex.Matcher.matches だった。

String fileName = "testfile.txt";
Pattern pattern = Pattern.compile("\\.txt$");
Matcher matcher = pattern.matcher(fileName);
String result   = (matcher.matches()) ? "マッチした" : "マッチしていない";
System.out.println(result);
// マッチしていない

これではマッチせず、さんざん悩んだ結果、Java正規表現API を見直すことにした。
結果、matches メソッドではなく、find メソッドに書き直した。

String fileName = "testfile.txt";
Pattern pattern = Pattern.compile("\\.txt$");
Matcher matcher = pattern.matcher(fileName);
String result   = (matcher.find()) ? "マッチした" : "マッチしていない";
System.out.println(result);
// マッチした

API の仕様の違い

matches()
matches() は、文字列全体がパターンにマッチしているかどうかを判定する。
find()
find() は、文字列の一部がパターンにマッチしているかどうかを判定する。

参照: java.util.regex クラス Matcher
他の言語から Java を利用した場合、なかなかこの違いに気が付かないよな…。