JavaScript Tips | 文字列ユーティリティ:URL 系 - 拡張子取得

JavaScript JavaScript
スポンサーリンク

何をしたいユーティリティか:「拡張子取得」

ここで作りたいのは、URL やパス文字列から「拡張子(.png や .js など)」だけを取り出す小さな関数です。

https://example.com/assets/logo.png"png"
/scripts/app.min.js"js"
/download/file""(拡張子なし)

こういう判定ができると、例えば次のようなことが簡単になります。

画像かどうかで処理を分ける。
ダウンロード時のアイコンを切り替える。
アップロードされたファイルの種類をざっくりチェックする。

そのための「拡張子取得ユーティリティ」を、URL を前提にかみ砕いて作っていきます。


拡張子取得の基本的な考え方

どこからどこまでを「拡張子」とみなすか

拡張子取得でやりたいことは、ざっくり言うとこうです。

  1. URL から「最後のパス部分」だけを取り出す(ファイル名っぽいところ)。
  2. その中で「最後のドット以降」を拡張子とみなす。
  3. ドットがなければ「拡張子なし」と判断する。

例えば、https://example.com/assets/logo.png なら、

URL 全体 → https://example.com/assets/logo.png
最後の / 以降 → logo.png
最後の . 以降 → png

という流れです。

逆に、/download/file のように . がなければ、拡張子はないと判断します。


一番シンプルな「拡張子取得」関数

URL 文字列から拡張子を取る getExtension

まずは、クエリやハッシュを無視して、「パス部分だけから拡張子を取る」関数を作ります。

function getExtension(url) {
  if (!url) return "";

  const str = String(url);

  const pathWithoutQuery = str.split(/[?#]/)[0];

  const lastSlashIndex = pathWithoutQuery.lastIndexOf("/");
  const filename =
    lastSlashIndex >= 0
      ? pathWithoutQuery.slice(lastSlashIndex + 1)
      : pathWithoutQuery;

  if (!filename) return "";

  const lastDotIndex = filename.lastIndexOf(".");
  if (lastDotIndex <= 0) {
    return "";
  }

  return filename.slice(lastDotIndex + 1).toLowerCase();
}
JavaScript

重要なポイントをかみ砕いて説明する

ここがこのユーティリティの心臓部なので、丁寧に見ていきます。

1. クエリやハッシュは先に切り落とす

const pathWithoutQuery = str.split(/[?#]/)[0];
JavaScript

URL には、? 以降のクエリや # 以降のハッシュが付いていることがあります。

/assets/logo.png?version=1#top

拡張子を取りたいのは「パス部分」だけなので、? または # で分割して、
一番前の部分だけを使います。

結果として、/assets/logo.png だけが残ります。

2. 最後の / 以降を「ファイル名」とみなす

const lastSlashIndex = pathWithoutQuery.lastIndexOf("/");
const filename =
  lastSlashIndex >= 0
    ? pathWithoutQuery.slice(lastSlashIndex + 1)
    : pathWithoutQuery;
JavaScript

/assets/logo.png のようなパスから、最後の / 以降を取り出します。

lastIndexOf("/") は「一番後ろの / の位置」を返します。
そこから +1 した位置から最後までを slice すると、logo.png になります。

もし / が含まれていない場合(単なる "logo.png" など)は、そのまま全体をファイル名とみなします。

3. ドットがなければ拡張子なし

if (!filename) return "";

const lastDotIndex = filename.lastIndexOf(".");
if (lastDotIndex <= 0) {
  return "";
}
JavaScript

lastIndexOf(".") で「一番後ろの .」を探します。

<= 0 のときは拡張子なしと判断しています。
理由はこうです。

"file"lastIndexOf(".") === -1 → ドットなし → 拡張子なし。
".gitignore"lastIndexOf(".") === 0 → 先頭のドット → 「隠しファイル名」とみなして拡張子なし。

.gitignore のような「先頭ドットのファイル」は、拡張子ではなく「ファイル名の一部」と考えるのが一般的なので、ここでは拡張子なし扱いにしています。

4. 最後のドット以降を小文字で返す

return filename.slice(lastDotIndex + 1).toLowerCase();
JavaScript

"logo.png"lastDotIndex"logo" の後ろ → slice(lastDotIndex + 1)"png"
"PHOTO.JPG""JPG" を取り出して toLowerCase()"jpg" に揃える。

拡張子は大文字・小文字が混ざることがあるので、
内部的には小文字に揃えて扱うのが実務では扱いやすいです。


実際の動きを例で確認する

典型的な URL の例

getExtension("https://example.com/assets/logo.png");
// "png"

getExtension("/scripts/app.min.js");
// "js"

getExtension("/images/photo.JPG");
// "jpg"

getExtension("/download/file");
// ""
JavaScript

最後の /download/file. がないので、拡張子なしとして空文字が返ってきます。

クエリやハッシュ付きの例

getExtension("/assets/logo.png?version=1");
// "png"

getExtension("/assets/logo.png#top");
// "png"

getExtension("/assets/logo.png?version=1#top");
// "png"
JavaScript

クエリやハッシュは先に切り落としているので、
拡張子取得には影響しません。

隠しファイルっぽい名前の例

getExtension("/config/.env");
// ""(拡張子なし扱い)

getExtension(".gitignore");
// ""(拡張子なし扱い)
JavaScript

先頭のドットは「拡張子」ではなく「ファイル名の一部」とみなしているため、
ここでは拡張子なしとして扱っています。


実務での使いどころと設計のポイント

「拡張子でざっくり分類する」用途に向いている

このユーティリティは、「拡張子ベースでざっくり分類したい」ときにとても便利です。

例えば、こんなコードが書けます。

const ext = getExtension(url);

if (["png", "jpg", "jpeg", "gif", "webp"].includes(ext)) {
  // 画像として扱う
} else if (["mp4", "webm"].includes(ext)) {
  // 動画として扱う
} else {
  // その他
}
JavaScript

アップロードされたファイルの種類をざっくりチェックしたり、
アイコンを切り替えたりするときに、拡張子取得はよく使われます。

「MIME タイプ判定」とは別物だと意識する

ここで作っているのは、あくまで「文字列としての拡張子」を取るだけのユーティリティです。

本当に安全にファイル種別を判定したい場合は、
サーバー側で MIME タイプを見たり、ファイルの中身をチェックしたりする必要があります。

フロント側の拡張子取得は、

  • 表示用のアイコンを決める
  • 軽いバリデーションをする

といった「ざっくり用途」に使う、という意識を持っておくと健全です。


ちょっとだけ手を動かしてみる

コンソールで、次のあたりを試してみてください。

getExtension("https://example.com/assets/logo.png");
getExtension("/scripts/app.min.js");
getExtension("/images/photo.JPG?size=large");
getExtension("/download/file");
getExtension("/config/.env");
JavaScript

「どのケースで何が返ってくるか」を、自分の目で確認してみてください。

そのうえで、自分のプロジェクトに

export function getExtension(url) { ... }
JavaScript

を置いて、

URL やパスから拡張子が欲しくなったら、
毎回 split(".") ではなく、必ず getExtension を通す、というルールにしてみてください。

それだけで、あなたの「拡張子判定」は、
場当たり的な文字列操作から、意図がはっきりした“業務レベルの拡張子取得ユーティリティ”に一段レベルアップします。

タイトルとURLをコピーしました