文字列を決まった文字数で切り詰める

長い文字列を指定した文字数で切って「…」を付ける方法をまとめます。slice() で絵文字が壊れる理由、スプレッド構文で足りない場面、Intl.Segmenter を使う書き方まで確かめます。

実行して検証済み処理系Node 22.22.3対応ES2015難易度●●○○○目安8更新

答え

日本語と英数字だけなら、slice() で足ります。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
こんにちは… 短い
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
👨‍👩‍👧と旅行に… あ🙂い… 短い

絵文字が混ざる可能性があるなら、Intl.Segmenter を使ってください。

javascript
console.log('短い'.slice(0, 5) + '…');
短い…
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
ちょうど五文字

長さを先に見る

切る前に長さを比べてください。 これを忘れると、短い文字列にも が付きます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
7 6
javascript
const text = 'あ🙂いうえお';
const cut = text.slice(0, 2);

console.log(cut.length);
console.log(cut === 'あ🙂');
2 false

slice() は範囲を超えてもエラーになりません。そのまま返します。 つまり「切られなかった」ことに気づけません。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
あ🙂い
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
false

を足す前に、切る必要があったかどうかを判定します。

slice() では足りない場面

slice() が数えているのは符号単位で、見た目の文字数ではありません。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
👨‍👩‍👧と true
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'The', 'quick', 'brown', 'fox' ]

見た目は6文字なのに、length7です。絵文字が2つ分だからです。

絵文字の途中で切ると壊れます。

と絵文字の前半だけが取れています。 画面には読めない記号が出ます。文字数の指定は守れても、中身が壊れます。

文字を正しく数える

スプレッド構文で足りるか

[...text]符号位置ごとに分けるので、絵文字は割れません。

多くの場面ではこれで十分です。

ただし、複数の絵文字が組み合わさったものは分解されます。

家族の絵文字は5つの符号位置でできています。 slice(0, 2) では、その2つ目までしか取れません。

Intl.Segmenter なら、見た目の1文字を1つとして数えます

どれを使うか

中身 使うもの
日本語・英数字だけと分かっている slice()
利用者が入力する文章 Intl.Segmenter
絵文字が1つずつしか出ない [...text] でも足りる

利用者が入れた文字列を切るなら Intl.Segmenter を選んでください。 入力欄に何が来るかは、こちらでは決められません。

Intl.Segmenter は毎回作らず、外に出して使い回すほうが速くなります。上の例は読みやすさのために中で作っています。

単語の途中で切りたくない

英語のように単語の区切りがある文章では、単語で区切ってから数える方法もあります。

isWordLike単語らしいものだけを残します。空白と記号は落ちます。

日本語には単語の区切りに空白がありませんが、Intl.Segmenter'ja' を指定すれば分けられます。

まとめ

  • 切る前に長さを比べる。 slice() は超えても落ちないので気づけない
  • slice() が数えるのは符号単位絵文字の途中で割れる
  • [...text] は符号位置ごと。多くの場面ではこれで足りる
  • 組み合わせた絵文字まで守るなら Intl.Segmenter
  • 利用者の入力を切るなら Intl.Segmenter 何が来るかは決められない

切り出しそのものの規則(負の数、範囲外、substring() との違い)はこちらにまとめてあります。 → 文字列を切り出す・整える

この記事の根拠

  1. String.prototype.slice — ECMAScript® 2026 Language Specificationtc39.es
  2. Intl.Segmenter — ECMAScript® 2026 Internationalization API Specificationtc39.es
  3. Unicode Standard Annex #29: Unicode Text Segmentationunicode.org

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)