はじめに
Javaの正規表現でつまずくポイントをまとめておきます。
他言語の正規表現をよく使う人ほどハマる気がします。
エスケープ文字
エスケープシーケンスを書く場合はエスケープ文字 \
を使用します。
が、JavaのString型で『バックスラッシュ』を表現したい場合は、エスケープシーケンスの1種である \\
を使用する必要があります。
私は丸1日無駄にしました。
コンパイルエラーを吐くコード
void check() {
if (isFind("hoge.com")) {
// 実行できない
}
}
boolean isFind(String text) {
// コンパイルエラー!!!!!
Pattern p = Pattern.compile("\.com");
return p.matcher(text).find();
}
コンパイルが通るコード
void check() {
if (isFind("hoge.com")) {
// 実行できる
}
}
boolean isFind(String text) {
Pattern p = Pattern.compile("\\.com");
return p.matcher(text).find();
}
要は、他言語におけるエスケープシーケンス \.
を表現したい場合は、 \\.
と書く必要があります、ということです。
このあたりの言い回しはややこしいため、コメント欄を参考にしてください。
Matcher#group(int)
をすぐには利用できない
Matcherクラスの group(int)
メソッドは、 find()
メソッドを利用しないと実行時エラーを吐きます。
というのも、 find()
メソッドで文字列のマッチを確認するためです。
group(int)
メソッドは、 find()
メソッドでマッチした文字列のゲッターでしかありません。
実行時エラーを吐くコード
Pattern p = Pattern.compile("(A*).");
void print() {
System.out.println(extract(AAABBB));
}
String extract(String text) {
Matcher m = p.matcher(text);
// 実行時エラー!!!!!
return m.group(1);
}
ちゃんと実行できるコード
Pattern p = Pattern.compile("(A*).");
void print() {
System.out.println(extract(AAABBB)); // 出力: AAA
}
String extract(String text) {
Matcher m = p.matcher(text);
if (m.find()) {
return m.group(1);
} else {
return "";
}
}
おわりに
正規表現は、言語によってかなり書き方が異なります。
1つの言語で得意になったと思っていると、痛い目にあうので気を付けましょう。
Perlはあんなに簡単なのに!