「file007」「商品 在庫45 棚12」のような文字列から、最後に出てくる数値だけを取り出したい場面があります。JavaScriptでは正規表現で簡潔に書けますが、「文字列の末尾」と「最後の数値」は別物で、ここを混同すると null が返って悩むことになります。
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) は配列の最後を負のインデックスで取れる便利なメソッドです。
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] でも同じ結果になります。undefined/null:数字が無いと match() は null を返し、?.at(-1) は undefined になります。既定値が欲しいときは ?? null(や ?? 0)でガードしてください。const str = "数字なし"; console.log(str.match(/\d+/g)?.at(-1) ?? null); // null(安全)
/\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 します。
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)
str.match(/\d+/g)?.at(-1) が確実です。すべての数値を配列で取り、.at(-1) で最後の要素を取得します。数値型にするには Number(...) で囲み、数字が無い場合に備えて ?? null でガードします。/\d+$/ で null になるのはなぜ?$ は文字列の末尾を表すため、/\d+$/ は「文字列が数字で終わる」ときしかマッチしません。"abc123xyz" は xyz で終わるので null です。位置を問わず最後の数値が欲しいときは match(/\d+/g)?.at(-1) を使ってください。name.replace(/\d+$/, m => String(Number(m) + 1).padStart(m.length, "0")) を使います。padStart で桁数を保つので "file007" は "file008"、"img099" は "img100" のように桁上がりも自然に処理できます。/-?\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は空白を誤判定するので避ける
関連として、文字列から数値のみ取得する方法(すべて)・文字列内の最初の数値を抽出する方法・文字列を数値型に変換する方法もあわせて確認すると、数値の扱いに強くなれます。
