JavaScript substring で文字列を位置指定で抽出

JavaScript の substring メソッドは、2 つのインデックス位置の間にある文字を抽出して新しい文字列を返します。開始インデックスと、省略可能な終了インデックス(この位置は含まない)を受け取り、開始位置から終了位置の直前までを取り出します。終了インデックスを省略すると、文字列の末尾まで抽出が続きます。slice と違い、substring は start が end を超えると引数を自動で入れ替えるため、意図しない空文字列を防げます。

テキスト抽出のための JavaScript substring の例

出力:

ここに出力が表示されます...

出力:

名前: report-2024
拡張子: csv

この例の仕組み

  1. filename.lastIndexOf(".")11 を返し、文字列内の最後のピリオド位置を示します。
  2. filename.substring(0, 11) はインデックス 0 から 11 の直前までを抽出し、"report-2024" を生成します。
  3. filename.substring(12) は終了引数を省略しているため、インデックス 12 から文字列末尾までを抽出して "csv" を返します。
  4. どちらの呼び出しも新しい文字列を返します。JavaScript の文字列はイミュータブルなので、元の filename は変更されません。

JavaScript substring でよくある間違い

負のインデックスが末尾基準で数えられると思い込む。

悪い例:

"hello".substring(-3); // "hello"("llo" ではない)

正しい例:

"hello".slice(-3); // "llo"

substring は負の値を 0 に丸めるため、substring(-3)substring(0) になり、文字列全体を返します。末尾基準のオフセットが必要なら slice を使います。

第 2 引数を長さとして扱う。

悪い例:

"abcdef".substring(2, 3); // "c"("cde" ではない)

正しい例:

"abcdef".substring(2, 5); // "cde"

第 2 引数は文字数ではなく終了インデックスです。この混同は、"abcdef".substr(2, 3)"cde" を返す旧式の substr(start, length) から起きやすくなります。substr から移行する場合は、start + length を終了インデックスに変換します。

JavaScript substring と slice の比較

挙動substring(start, end)slice(start, end)
負の引数0 に丸められる文字列末尾から数える
start > end自動で引数を入れ替える空文字列 "" を返す
範囲外インデックスstring.length に丸められるstring.length に丸められる
元の文字列を変更するかしないしない

インデックス計算の結果が逆順になる可能性があるなら substring を使います。自動スワップにより必ず有効な結果になります。str.slice(-N) で末尾 N 文字を取り出すように、負のオフセットを意図して使う場合は slice を選びます。

非推奨の substr を substring に置き換える

旧式の substr(start, length) メソッド(JavaScript substr と呼ばれることが多い)は、古いコードで今も見かけますが、ドキュメントでは非推奨です。JavaScript substr substring の混同は、第 2 引数の意味が異なることから起こります。substr は長さ、substring は終了インデックスを受け取ります。安全に移行するには次の手順を使います。

  1. str.substr(start, length)str.substring(start, start + length) に置き換えます。
  2. start が負になる可能性がある場合は slice(start, start + length) に切り替えます。substring は負値を 0 に丸めるためです。
  3. length0、負数、省略のケースをテストします。これらの入力では substrsubstring の挙動が分岐します。

FAQ

JavaScript substring と slice の違いは何ですか?

どちらもインデックス指定で文字列の一部を取り出しますが、境界ケースの扱いが異なります。substring は負の引数を 0 に丸め、start が大きいと start/end を入れ替えます。slice は負の値を末尾からのオフセットとして扱い、start が end を超えると空文字列を返します。通常の前方向抽出では両者は同じ結果になります。

JavaScript substring は元の文字列を変更しますか?

いいえ。JavaScript の文字列はイミュータブルで、すべての文字列メソッドは新しい文字列を返します。substring を呼んでも元の文字列は変わりません。抽出結果を保持したい場合は変数に代入します。

substring で start が end より大きいとどうなりますか?

substring は 2 つの引数を自動で入れ替えます。"abcdef".substring(4, 1)"abcdef".substring(1, 4) と同じ扱いになり、"bcd" を返します。この正規化により、インデックス計算で順序が逆になっても空文字列になりにくくなります。