「後方一致」とは何をしているのか
前回の「前方一致」は“先頭が合っているか”を見るものでした。
「後方一致」はその逆で、文字列の“末尾”が、指定した文字列と一致しているかどうかを調べます。
「report.csv」が「.csv」で終わっているか?
「photo.jpg」が「.png」では終わっていないか?
「/api/users/123」が「/users」で終わっているか?
こういう判定が全部「後方一致」です。
ファイル拡張子のチェック、URL の末尾パスの判定、メッセージの末尾タグの確認など、
業務コードのあちこちで出てきます。
JavaScript 標準の endsWith の基本
いちばんシンプルな使い方
JavaScript には、後方一致専用のメソッド endsWith が用意されています。
const file = "report.csv";
file.endsWith(".csv"); // true
file.endsWith(".txt"); // false
JavaScript「この文字列は、指定した文字列で“終わっているか”?」を true / false で返してくれます。
第二引数で「どこまでを対象とするか」も指定できます。
const str = "HelloWorld";
str.endsWith("World"); // true(全体で判定)
str.endsWith("Hello", 5); // true(先頭から5文字分 "Hello" までを対象に判定)
str.endsWith("World", 5); // false("Hello" の中には "World" はない)
JavaScriptここでの重要ポイントは二つです。
文字列の“末尾”だけを見る、ということ。
大文字・小文字は区別される、ということ。
"report.CSV".endsWith(".csv"); // false(大文字小文字が違う)
JavaScript業務で使いやすくする:大文字・小文字を無視した後方一致
実務では、「拡張子は大文字でも小文字でもいい」といったケースが多いです。.CSV でも .csv でも同じ扱いにしたい、というやつですね。
そこで、「大文字・小文字を無視した後方一致」ユーティリティを用意します。
function endsWithIgnoreCase(text, suffix) {
if (text == null || suffix == null) return false;
const t = String(text).toLowerCase();
const s = String(suffix).toLowerCase();
if (s === "") return true; // 空文字は「常に末尾一致」とみなす
return t.endsWith(s);
}
JavaScriptやっていることを噛み砕きます。
null / undefined が来ても落ちないようにしている。
両方を文字列化してから toLowerCase() で小文字にそろえる。
サフィックス(末尾文字列)が空なら true(検索 UI 的に自然)。
最後は endsWith で後方一致を判定する。
使い方はこうです。
endsWithIgnoreCase("report.CSV", ".csv"); // true
endsWithIgnoreCase("photo.jpg", ".JPG"); // true
endsWithIgnoreCase("document.pdf", ".doc"); // false
JavaScriptこれだけで、「大文字・小文字を気にしない後方一致」がどこでも同じ挙動で使えます。
日本語環境らしく:全角・半角も吸収した後方一致
日本語の業務システムだと、「全角・半角の揺れ」もよく問題になります。
例えば、ユーザーが「.csv」(全角ドット+全角英字)と入力してしまうことがあります。
それでも「.csv」と同じものとして扱いたい、という要望は普通にあります。
そこで、「検索用の正規化」を一箇所にまとめてから endsWith する形にします。
function toHalfWidth(str) {
if (str == null) return "";
return String(str)
.replace(/[!-~]/g, (ch) =>
String.fromCharCode(ch.charCodeAt(0) - 0xFEE0)
)
.replace(/ /g, " ");
}
function normalizeForSuffix(str) {
return toHalfWidth(str).toLowerCase().trimEnd();
}
JavaScriptここでは、
全角英数字・記号を半角に寄せる。
全角スペースを半角スペースにする。
小文字にそろえる。
末尾の空白だけ削る(後方一致なので末尾が大事)。
という正規化をしています。
これを使って、「ゆるい後方一致」を作ります。
function endsWithLoose(text, suffix) {
if (text == null || suffix == null) return false;
const t = normalizeForSuffix(text);
const s = normalizeForSuffix(suffix);
if (s === "") return true;
return t.endsWith(s);
}
JavaScript動きを見てみます。
endsWithLoose("report.CSV", ".csv"); // true(全角ドット+全角英字)
endsWithLoose("photo.JPG ", ".jpg"); // true(末尾スペース無視+大文字小文字無視)
endsWithLoose("log_2026-02-19 ", "2026-02-19"); // true(末尾の全角スペース無視)
endsWithLoose("document.pdf", ".doc"); // false
JavaScriptここでの一番大事なポイントは、
「後方一致の前に“どう正規化するか”をユーティリティに閉じ込めている」ことです。
呼び出し側は endsWithLoose を呼ぶだけで、
大文字・小文字・全角・半角・末尾スペースを意識せずに済みます。
業務での具体的な使いどころ
ファイル拡張子のチェック
アップロードされたファイルが、許可された拡張子かどうかを判定するのは定番です。
function isCsvFile(name) {
return endsWithIgnoreCase(name, ".csv");
}
function isImageFile(name) {
return (
endsWithIgnoreCase(name, ".png") ||
endsWithIgnoreCase(name, ".jpg") ||
endsWithIgnoreCase(name, ".jpeg")
);
}
isCsvFile("report.csv"); // true
isCsvFile("REPORT.CSV"); // true
isImageFile("photo.JPG"); // true
isImageFile("document.pdf"); // false
JavaScriptここで endsWithIgnoreCase を使っておくと、
「.CSV だから弾かれた」といった微妙な不具合を防げます。
URL やパスの末尾判定
API のエンドポイントやルーティングで、
「末尾が /users のパスだけを対象にしたい」といったケースもあります。
function isUsersPath(path) {
return endsWithLoose(path, "/users");
}
isUsersPath("/api/v1/users"); // true
isUsersPath("/api/v1/users/123"); // false
isUsersPath("/USERS"); // true(大文字小文字無視)
JavaScript「どこに /users が含まれているか」ではなく、
「最後が /users で終わっているか」を見たいときは、
部分一致ではなく後方一致が適切です。
メッセージの末尾タグ・サフィックス判定
ログやメッセージの末尾に、[OK] や [NG] のようなタグを付けることがあります。
function isOkMessage(message) {
return endsWithLoose(message, "[ok]");
}
isOkMessage("処理完了 [OK]"); // true
isOkMessage("処理失敗 [NG]"); // false
JavaScript「最後に何が付いているか」で判定したいとき、
後方一致はとても素直に書けます。
設計として意識してほしいこと
「後方一致のルール」をユーティリティに閉じ込める
一番大事なのは、
「後方一致のとき、何を無視して、何を区別するか」を決めて、
それをユーティリティに閉じ込めることです。
大文字・小文字を無視するのか。
全角・半角をそろえるのか。
末尾の空白を無視するのか。
これを機能ごとにバラバラに書き始めると、
「この画面では .CSV が通るのに、あっちでは通らない」といった
気持ち悪い差がどんどん増えていきます。
なので、
normalizeForSuffix のような「後方一致用の正規化関数」を一つ決める。
後方一致をしたいときは、必ず endsWithIgnoreCase や endsWithLoose を通す。
というルールにしておくと、
ファイルチェック・URL 判定・メッセージ判定の挙動が一貫して、テストもしやすくなります。
ちょっとだけ手を動かしてみる
コンソールで、次のあたりを試してみてください。
"report.csv".endsWith(".csv");
"report.CSV".endsWith(".csv");
endsWithIgnoreCase("report.CSV", ".csv");
endsWithLoose("report.CSV ", ".csv");
endsWithLoose("log_2026-02-19 ", "2026-02-19");
JavaScript「どこからが true で、どこからが false になるか」を体で覚えると、
「後方一致」と「正規化」のイメージがかなりクリアになります。
そのうえで、自分のプロジェクトに
export function endsWithIgnoreCase(text, suffix) { ... }
export function endsWithLoose(text, suffix) { ... }
JavaScriptのようなユーティリティを一つ置いて、
「拡張子チェックや末尾判定は必ずここを通す」
というルールにしてみてください。
それができた瞬間、あなたの文字列判定は
「その場しのぎの endsWith の寄せ集め」から
「設計された後方一致ユーティリティ」に、一段レベルアップします。
