後方一致は「この文字列で終わっているか」を見るシンプルな判定
後方一致は、
「文字列が、ある決まった文字列で“終わっているか”どうか」を調べるテクニックです。
ファイル名が .csv で終わるものだけ処理したい。
メールアドレスが @example.com で終わるか確認したい。
URLが /api で終わるものだけ特別扱いしたい。
こういうときに使うのが後方一致です。
Java には String#endsWith が用意されていて、これをユーティリティとして包んでおくと、
業務コードがかなり読みやすく、かつ安全になります。
基本形:endsWith をそのままラップする
一番シンプルな後方一致ユーティリティ
まずは、Java標準の endsWith をそのまま使う形からいきます。
public final class SuffixMatcher {
private SuffixMatcher() {}
public static boolean endsWith(String text, String suffix) {
if (text == null || suffix == null) {
return false;
}
return text.endsWith(suffix);
}
}
Java使い方はこんな感じです。
System.out.println(SuffixMatcher.endsWith("report.csv", ".csv")); // true
System.out.println(SuffixMatcher.endsWith("image.png", ".csv")); // false
System.out.println(SuffixMatcher.endsWith("user@example.com", "@example.com")); // true
System.out.println(SuffixMatcher.endsWith("user@other.com", "@example.com")); // false
System.out.println(SuffixMatcher.endsWith(null, ".csv")); // false
System.out.println(SuffixMatcher.endsWith("report.csv", null)); // false
Javaここで押さえておきたい重要ポイントは二つあります。
一つ目は、「null の扱いをユーティリティ側で決めている」ことです。text か suffix が null のときにどうするかを、
「false を返す」というポリシーで固定しています。
これを決めておくと、呼び出し側で毎回 null チェックを書かなくて済み、
コードの抜け漏れも減ります。
二つ目は、「業務コードから endsWith の生呼び出しを隠している」ことです。
生で text.endsWith(".csv") をあちこちに書くと、
null チェックの抜けや、大小文字の扱いのバラつきが出やすくなります。
ユーティリティにまとめることで、「後方一致のルール」を一箇所に集約できます。
大文字小文字を無視した後方一致
toLowerCase / toUpperCase で正規化してから比較する
英字を扱うときに必ず出てくるのが「大文字小文字を区別するかどうか」です。
例えば、拡張子 .CSV も .csv も .CsV も、全部「CSVファイル」として扱いたい、というケースはよくあります。
その場合は、両方を同じ大文字・小文字に揃えてから endsWith します。
public static boolean endsWithIgnoreCase(String text, String suffix) {
if (text == null || suffix == null) {
return false;
}
String t = text.toLowerCase();
String s = suffix.toLowerCase();
return t.endsWith(s);
}
Java使い方はこうです。
System.out.println(
SuffixMatcher.endsWithIgnoreCase("report.CSV", ".csv")
); // true
System.out.println(
SuffixMatcher.endsWithIgnoreCase("report.csv", ".CSV")
); // true
System.out.println(
SuffixMatcher.endsWithIgnoreCase("image.png", ".csv")
); // false
Javaここで深掘りしたい重要ポイントは、「正規化(normalize)してから判定する」という考え方です。
やっていることはシンプルで、
文字列全体を小文字に変換する
サフィックスも小文字に変換する
そのうえで endsWith する
というだけです。
この「前処理(正規化)+本処理(後方一致)」という分け方は、
部分一致・完全一致・検索など、文字列処理全般でとても重要なパターンです。
「何を無視して、何を区別するか」を前処理で決めてしまうと、
本処理のコードがスッキリします。
前後の空白や改行をどう扱うか
「見た目としてそのサフィックスで終わっていればOK」にしたい場合
外部ファイルやユーザー入力では、
末尾に空白や改行が紛れ込むことがよくあります。
例えば、"report.csv "(末尾に空白)や "report.csv\n"(末尾に改行)も、
「.csv で終わっている」とみなしたいことがあります。
その場合は、後方一致の前に「前後の空白を取り除く」正規化を挟みます。
public static boolean endsWithTrimmed(String text, String suffix) {
if (text == null || suffix == null) {
return false;
}
String t = text.strip(); // 前後の空白(全角スペースや改行も含む)を削除(Java 11以降)
String s = suffix.strip();
return t.endsWith(s);
}
Java使い方はこうです。
System.out.println(
SuffixMatcher.endsWithTrimmed("report.csv ", ".csv")
); // true
System.out.println(
SuffixMatcher.endsWithTrimmed("report.csv\n", ".csv")
); // true
System.out.println(
SuffixMatcher.endsWithTrimmed("report.csv\t", ".csv")
); // true
Javaここでのポイントは、「どこまで正規化するかは要件次第」ということです。
前後の空白だけを無視するのか、
タブや改行も無視するのか、
全角・半角の違いも吸収するのか。
全部を一気にやろうとすると複雑になるので、
まずは「前後の空白を削る」「大文字小文字を揃える」くらいから始めて、
必要に応じて正規化の範囲を広げていくのが現実的です。
実務での後方一致の使いどころ
例1:ファイル拡張子チェックユーティリティ
ファイルアップロード機能などでは、
「CSVだけ受け付ける」「画像ファイルだけ受け付ける」といったチェックがよく出てきます。
後方一致を使って、拡張子チェックのユーティリティを書いてみます。
public final class FileTypeChecker {
private FileTypeChecker() {}
public static boolean isCsv(String fileName) {
if (fileName == null || fileName.isBlank()) {
return false;
}
return SuffixMatcher.endsWithIgnoreCase(fileName.strip(), ".csv");
}
public static boolean isImage(String fileName) {
if (fileName == null || fileName.isBlank()) {
return false;
}
String name = fileName.strip();
return SuffixMatcher.endsWithIgnoreCase(name, ".png")
|| SuffixMatcher.endsWithIgnoreCase(name, ".jpg")
|| SuffixMatcher.endsWithIgnoreCase(name, ".jpeg")
|| SuffixMatcher.endsWithIgnoreCase(name, ".gif");
}
}
Java使い方はこうです。
System.out.println(FileTypeChecker.isCsv("report.csv")); // true
System.out.println(FileTypeChecker.isCsv("report.CSV ")); // true
System.out.println(FileTypeChecker.isCsv("report.txt")); // false
System.out.println(FileTypeChecker.isImage("photo.png")); // true
System.out.println(FileTypeChecker.isImage("photo.JPG")); // true
System.out.println(FileTypeChecker.isImage("document.pdf"));// false
Javaここでの重要ポイントは、「低レベルな後方一致を“意味のある判定”に昇華している」ことです。
単に endsWith を呼ぶのではなく、
「CSVかどうか」「画像ファイルかどうか」というビジネス的な意味に変換しています。
こうやって、「文字列操作」を「ドメインの概念」に橋渡しするのが、
実務ユーティリティの本当の価値です。
例2:ドメイン制限付きメールアドレスチェック
「自社ドメインのメールアドレスだけ許可したい」という要件もよくあります。
例えば、@example.com で終わるメールアドレスだけOKにするユーティリティは、こう書けます。
public final class MailDomainChecker {
private MailDomainChecker() {}
public static boolean isFromCompanyDomain(String email) {
if (email == null || email.isBlank()) {
return false;
}
String normalized = email.strip().toLowerCase();
return normalized.endsWith("@example.com");
}
}
JavaSystem.out.println(
MailDomainChecker.isFromCompanyDomain("user@example.com")
); // true
System.out.println(
MailDomainChecker.isFromCompanyDomain("USER@EXAMPLE.COM ")
); // true
System.out.println(
MailDomainChecker.isFromCompanyDomain("user@other.com")
); // false
Javaここでも、「strip で前後の空白を削る」「toLowerCase で小文字に揃える」という正規化をしてから、
後方一致で判定しています。
まとめ:後方一致ユーティリティで身につけたい感覚
後方一致は、「この文字列が、指定した文字列で終わっているか」を見る、
とてもシンプルなテクニックです。
まずは
endsWith をそのままラップした基本版
大文字小文字を無視する endsWithIgnoreCase
前後の空白を削ってから判定する endsWithTrimmed
といったユーティリティを用意して、
「null の扱い」「正規化の方針」を自分のプロジェクト内で統一してみてください。
そのうえで、
拡張子チェック
メールアドレスのドメイン制限
特定のサフィックスを持つIDやURLの判定
のような「意味のある判定」に組み込んでいくと、
後方一致が単なる文字列操作ではなく、
業務ロジックの一部としてしっかり機能し始めます。
もしあなたのコードのどこかに、
if (fileName.endsWith(".csv")) { ... }
のような生の条件が散らばっているなら、
それを一度 FileTypeChecker や SuffixMatcher のようなユーティリティに集約してみてください。
その小さな整理が、
「読みやすくて変更に強い文字列処理」を書けるエンジニアへの、確かな一歩になります。
