【JavaScript】文字列内の最後にある数値を取得する方法|match(/\d+/g).at(-1)と末尾固定/$/の違い・連番処理まで

file007」「商品 在庫45 棚12」のような文字列から、最後に出てくる数値だけを取り出したい場面があります。JavaScriptでは正規表現で簡潔に書けますが、「文字列の末尾」と「最後の数値」は別物で、ここを混同すると null が返って悩むことになります。

この記事の結論:数値が文字列のどこにあっても最後の1個が欲しいなら str.match(/\d+/g)?.at(-1)文字列が数字で終わっていると分かっているなら str.match(/\d+$/)?.[0] を使います。/\d+$/ は末尾固定なので、"abc123xyz" のように数字で終わらない文字列では null になる点に注意します。
スポンサーリンク

match(/\d+/g) + at(-1) で最後の数値を取得する(推奨)

もっとも確実な方法です。グローバルフラグ g 付き/\d+/g で数値をすべて配列に取り出し、.at(-1) で末尾の要素(=最後の数値)を取ります。.at(-1) は配列の最後を負のインデックスで取れる便利なメソッドです。

match(/\d+/g).at(-1)
const str = "ファイルabc123def456";

const last = str.match(/\d+/g)?.at(-1);
console.log(last);         // "456"(文字列)
console.log(Number(last)); // 456(数値)
この方法は数値が文字列の末尾になくても動きます。"abc123xyz" でも最後の数値 "123" が取れます。.at(-1) の代わりに arr[arr.length - 1] でも同じ結果になります。
マッチしないと undefinednull数字が無いと match()null を返し、?.at(-1)undefined になります。既定値が欲しいときは ?? null(や ?? 0)でガードしてください。
数字が無いケース
const str = "数字なし";

console.log(str.match(/\d+/g)?.at(-1) ?? null); // null(安全)

/\d+$/ は「文字列が数字で終わる」とき専用

$文字列の末尾を表すアンカーです。/\d+$/ は「末尾にある連続数字」にマッチしますが、文字列が数字で終わっていないとマッチしません。ファイル名の連番のように末尾が数値だと確定しているケース向けです。

末尾固定の /\d+$/
console.log("item045".match(/\d+$/)?.[0]);        // "045"(末尾が数字 → OK)
console.log("a12b".match(/\d+$/)?.[0] ?? null);   // null(末尾が "b" → 取れない)
ここが旧来よくある誤りです:/\d+$/ で「最後の数値」を取ろうとすると、"abc123xyz" のように数字で終わらない文字列で null になります。位置を問わず最後の数値が欲しいときは match(/\d+/g)?.at(-1) を使ってください。

小数やマイナス符号を含む最後の数値を取る

\d+ は整数の連続にしかマッチしないため、-3.5 は符号や小数点で分断されます。/-?\d+(?:\.\d+)?/g に広げて .at(-1) を取れば、マイナスや小数を含む最後の数値を取得できます。

小数・マイナス対応
const str = "差分は+10、最終-3.5";

const last = str.match(/-?\d+(?:\.\d+)?/g)?.at(-1);
console.log(last);         // "-3.5"
console.log(Number(last)); // -3.5

1文字ずつ後ろから処理する方法

正規表現を使わず、文字列の末尾から1文字ずつ調べる方法もあります。ポイントは数字を範囲(c >= "0" && c <= "9")で判定すること。!isNaN(c) だと isNaN(" ")false のため空白を数字と誤判定してしまうので避けます。

後ろから連続する桁を集める
function getLastNumber(str) {
  let last = "";
  for (let i = str.length - 1; i >= 0; i--) {
    const c = str[i];
    if (c >= "0" && c <= "9") {
      last = c + last;       // 後ろから桁をつなぐ
    } else if (last !== "") {
      break;                 // 数字が途切れたら終了
    }
  }
  return last || null;
}

console.log(getLastNumber("abc123xyz")); // "123"(末尾が数字でなくてもOK)
console.log(getLastNumber("a12 "));      // "12"(末尾の空白は無視)
手書きの反復処理は行数が増えがちです。特別な事情がなければ str.match(/\d+/g)?.at(-1) の1行で十分です。

方法の使い分け

状況 書き方
どこにあっても最後の数値(推奨) str.match(/\d+/g)?.at(-1)
文字列が数字で終わると確定 str.match(/\d+$/)?.[0]
小数・マイナスも含める str.match(/-?\d+(?:\.\d+)?/g)?.at(-1)
最初の数値が欲しい str.match(/\d+/)?.[0]
すべての数値が欲しい str.match(/\d+/g)

実用例:ファイル名末尾の連番を +1 する

末尾の数値を取り出すニーズで多いのが連番のインクリメントです。replace(/\d+$/, ...) でコールバックを使い、padStart桁数(ゼロ埋め)を維持したまま +1 します。

連番を +1(ゼロ埋め維持)
function nextName(name) {
  return name.replace(/\d+$/, m =>
    String(Number(m) + 1).padStart(m.length, "0")
  );
}

console.log(nextName("file007")); // "file008"
console.log(nextName("img099"));  // "img100"(桁上がりも自然)

よくある質問(FAQ)

Q文字列の最後にある数値を取り出すには?
Astr.match(/\d+/g)?.at(-1) が確実です。すべての数値を配列で取り、.at(-1) で最後の要素を取得します。数値型にするには Number(...) で囲み、数字が無い場合に備えて ?? null でガードします。
Q/\d+$/ で null になるのはなぜ?
A$文字列の末尾を表すため、/\d+$/ は「文字列が数字で終わる」ときしかマッチしません。"abc123xyz"xyz で終わるので null です。位置を問わず最後の数値が欲しいときは match(/\d+/g)?.at(-1) を使ってください。
Q末尾の連番を1増やしたい(ファイル名など)。
Aname.replace(/\d+$/, m => String(Number(m) + 1).padStart(m.length, "0")) を使います。padStart で桁数を保つので "file007""file008""img099""img100" のように桁上がりも自然に処理できます。
Q小数やマイナスの最後の数値を取りたい場合は?
A/-?\d+(?:\.\d+)?/g で取得して .at(-1) を使います。-? でマイナス、(?:\.\d+)? で小数部に対応し、"差分+10 最終-3.5" から -3.5 が取り出せます。

まとめ

JavaScriptで文字列内の最後にある数値を取得する方法のポイントを整理します。

  • 基本は str.match(/\d+/g)?.at(-1)(位置を問わず最後を取れる)
  • /\d+$/文字列が数字で終わるとき専用"abc123xyz"null
  • 小数・マイナスは /-?\d+(?:\.\d+)?/g
  • 連番+1は replace(/\d+$/, ...)padStart でゼロ埋め維持
  • 後方反復は範囲判定で。isNaN は空白を誤判定するので避ける

関連として、文字列から数値のみ取得する方法(すべて)文字列内の最初の数値を抽出する方法文字列を数値型に変換する方法もあわせて確認すると、数値の扱いに強くなれます。