JavaScriptで「文字列の末尾から3文字だけ取り出したい」のように、後ろ(末尾)から指定した文字数を取得したい場面はよくあります。カード番号の下4桁を取り出したり、ファイルや識別子の末尾の区分だけを見たりするケースです。
結論はシンプルで、負のインデックスに対応した slice(-文字数) を使います。この記事では基本の取得方法から、substring() での書き方、「末尾0文字」を取りたいのに全文が返る -0 の罠、絵文字を含むときの挙動、そして紛らわしい「末尾N文字を削除して前を取得」との違いまで解説します。
str.slice(-n) が基本です。(末尾からN文字を削除して前が欲しい場合は str.slice(0, -n) と、引数の渡し方で逆の意味になる点に注意してください。)slice() で末尾からN文字を取得する(推奨)
slice() は負の値を「末尾からの位置」として扱えるため、slice(-文字数) だけで末尾N文字を取得できます。
const str = "abcdefg"; const n = 3; // 取得したい文字数 const result = str.slice(-n); console.log(result); // "efg"
substring() で取得する
substring() は負のインデックスに対応していないため、開始位置を 文字列の長さ − 文字数 で計算して渡します。
const str = "abcdefg"; const n = 3; const result = str.substring(str.length - n); console.log(result); // "efg"
【重要】「末尾0文字」と文字数オーバーの挙動
変数で文字数を渡すとき、slice(-n) にはn が 0 のとき全文が返るという落とし穴があります。JavaScriptでは -0 が 0 と等しいため、slice(-0) は slice(0) と同じ=先頭からの全文になるためです。
const str = "abcdefg";
console.log(str.slice(-0)); // "abcdefg"(""ではなく全文! -0 は 0 と同じ)
console.log(str.slice(-10)); // "abcdefg"(文字数が長すぎても全文・エラーなし)
// n が 0 でも安全に「空文字」にしたいなら length 基準で書く
function lastN(str, n) {
return str.slice(str.length - n); // n=0 のとき slice(length) → ""
}
console.log(lastN(str, 0)); // ""(意図通り0文字)
console.log(lastN(str, 3)); // "efg"
slice(-n) は n === 0 で全文を返してしまいます。slice(str.length - n) や n === 0 ? "" : str.slice(-n) のように書くと安全です。なお文字数が文字列より長い場合は、どちらも全文を返すだけでエラーにはなりません。【混同注意】「末尾N文字を削除して前を取得」との違い
「後ろからN文字」も、末尾N文字を取得するのか、末尾N文字を削除して前を取得するのかで真逆になります。slice() の引数で切り替わるので整理しておきましょう。
const str = "abcdefg"; const n = 3; // 末尾から n 文字を「取得」する console.log(str.slice(-n)); // "efg" // 末尾から n 文字を「削除」して前を取得する console.log(str.slice(0, -n)); // "abcd"
【注意】絵文字・サロゲートペアを含む場合
slice() はUTF-16のコード単位で数えるため、末尾の文字が絵文字(😀 など)のように2コード単位で1文字のサロゲートペアだと、途中で切れて文字化けします。見た目の1文字(コードポイント)単位で取得したいときは [...str] で配列化してから切り出します。
// 末尾が絵文字(\u{1F600} = 絵文字1文字)の文字列
const str = "ab\u{1F600}";
console.log(str.slice(-1)); // 壊れた半端な文字(絵文字の片割れ)
// 対策: コードポイント単位で取得
function lastChars(str, n) {
if (n <= 0) return ""; // slice(-0) は全文が返るため 0 以下は明示的に空文字に
return [...str].slice(-n).join("");
}
console.log(lastChars(str, 1)); // 絵文字1文字(壊れない)
console.log(lastChars(str, 2)); // "b" + 絵文字
方法の使い分け
| やりたいこと | 書き方 |
|---|---|
| 末尾からN文字を取得 | str.slice(-n) / str.substring(str.length - n) |
| 末尾N文字を削除して前を取得 | str.slice(0, -n) |
| n が 0 でも安全に取得 | str.slice(str.length - n) |
| 絵文字を崩さず末尾N文字 | [...str].slice(-n).join("") |
| 先頭からN文字を取得 | str.slice(0, n)(詳細) |
実用例:カード番号の下4桁を取得する
伏せ字表示などでよく使う「末尾4桁」も slice(-4) で簡潔に取得できます。
const card = "1234567812345678"; const last4 = card.slice(-4); console.log(last4); // "5678" // 下4桁以外を伏せ字にする const masked = "*".repeat(card.length - 4) + last4; console.log(masked); // "************5678"
よくある質問(FAQ)
str.slice(-n) です。負の値を渡すと末尾からの位置として扱われるため、slice(-3) で末尾3文字を取得できます。substring() は負の値に対応しないので str.substring(str.length - n) と書きます。slice(-n) は末尾からN文字を取得("efg")、slice(0, -n) は末尾N文字を削除して前を取得("abcd")します。-0 が 0 と等しく、slice(-0) が slice(0)(全文)になるためです。n が 0 になりうる場合は str.slice(str.length - n) や n === 0 ? "" : str.slice(-n) と書くと意図どおり空文字になります。slice() はUTF-16のコード単位で数え、絵文字(サロゲートペア)は2単位で1文字だからです。[...str].slice(-n).join("") のようにコードポイント単位の配列にしてから取得すると、見た目の文字数で正しく切り出せます。まとめ
JavaScriptで文字列の後ろから指定した文字数を取得する方法のポイントを整理します。
- 末尾からN文字の取得は
str.slice(-n)(substring(str.length - n)も同じ) slice(-0)は全文が返る(-0 === 0)。n が 0 になりうるならslice(str.length - n)- 文字数が長すぎてもエラーにならず全文が返る
slice(-n)(取得)とslice(0, -n)(末尾N文字を削除して前)は逆の意味- 絵文字を含むなら
[...str].slice(-n).join("")でコードポイント単位に
対になる先頭から指定した文字数を取得する方法や、開始位置と文字数を指定して取得する方法、特定の文字の直前・直後の1文字を取得する記事もあわせて確認すると理解が深まります。
