JavaScript substring で文字列を位置指定で抽出
JavaScript の substring メソッドは、2 つのインデックス位置の間にある文字を抽出して新しい文字列を返します。開始インデックスと、省略可能な終了インデックス(この位置は含まない)を受け取り、開始位置から終了位置の直前までを取り出します。終了インデックスを省略すると、文字列の末尾まで抽出が続きます。slice と違い、substring は start が end を超えると引数を自動で入れ替えるため、意図しない空文字列を防げます。
テキスト抽出のための JavaScript substring の例
出力:
ここに出力が表示されます...
出力:
名前: report-2024
拡張子: csv
この例の仕組み
filename.lastIndexOf(".")は11を返し、文字列内の最後のピリオド位置を示します。filename.substring(0, 11)はインデックス0から11の直前までを抽出し、"report-2024"を生成します。filename.substring(12)は終了引数を省略しているため、インデックス12から文字列末尾までを抽出して"csv"を返します。- どちらの呼び出しも新しい文字列を返します。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 は終了インデックスを受け取ります。安全に移行するには次の手順を使います。
str.substr(start, length)をstr.substring(start, start + length)に置き換えます。startが負になる可能性がある場合はslice(start, start + length)に切り替えます。substringは負値を0に丸めるためです。lengthが0、負数、省略のケースをテストします。これらの入力ではsubstrとsubstringの挙動が分岐します。
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" を返します。この正規化により、インデックス計算で順序が逆になっても空文字列になりにくくなります。