substr一覧

JavaScriptで文字列を切り出す方法(slice/substring/substr)

文字列の一部を切り出して利用する処理は、実に様々な場面で必要です。この記事では、文字列の切り出しに使えるメソッドの紹介や使い分けについてまとめます。

Stringの3つのメソッド

slice

構文

string.slice(開始位置, [終了位置])
  • 開始位置は、終了位置より小さい数値を指定します。
  • 終了位置を省略すると、開始位置から末尾まで切り出されます。
  • 負の数を指定した場合、末尾からの文字数となります。

使用例

const string = 'あいうえおかきくけこさしすせそ';

console.log(string.slice(5, 10));
// かきくけこ

console.log(string.slice(5));
// かきくけこさしすせそ

console.log(string.slice(-10, -5));
// かきくけこ

substring

構文

string.substring(開始位置, [終了位置])
  • 開始位置と終了位置はどちらが大きくても構いません。開始位置のほうが大きい場合は、開始位置と終了位置を入れ替えたものとして処理されます。
  • 終了位置を省略すると、開始位置から末尾まで切り出されます。
  • 開始位置や終了位置に負の数を指定すると、0として扱われます。

使用例

const string = 'あいうえおかきくけこさしすせそ';

console.log(string.substring(5, 10));
// かきくけこ

console.log(string.substring(10, 5));
// かきくけこ

console.log(string.substring(5));
// かきくけこさしすせそ

console.log(string.substring(-5));
// あいうえおかきくけこさしすせそ

substr

構文

string.substr(開始位置, [文字数])
  • 文字数を省略すると、開始位置から末尾まで切り出されます。
  • 開始位置に負の数を指定した場合、末尾からの文字数となります。
  • 文字数に負の数を指定すると、0として扱われます。

使用例

const string = 'あいうえおかきくけこさしすせそ';

console.log(string.substr(5, 5));
// かきくけこ

console.log(string.substr(5));
// かきくけこさしすせそ

console.log(string.substr(-5));
// さしすせそ

どのメソッドを使うべきか?

パフォーマンスの差はほとんど無い

パフォーマンス比較によく用いられるjsPerfというWebサービスがあり、この記事に挙げたメソッドを比較するテストがありました。

わずかにsubstringが優勢なケースが多いように見えますが、気にするほどの差ではありません。

Webブラウザの互換性にも差は見られない

slicesubstringsubstrのいずれも、初期のJavaScriptから存在するメソッドで、Webブラウザでの互換性も十分確保されています。
そのため、互換性を軸に、使用するメソッドを選ぶ必要はありません。

substrは標準メソッドではない

3つのメソッドのうちsubstrについては、JavaScriptの標準仕様であるECMAScriptにおいて、仕様本編ではなく付録(Annex)での定義となっており、いわゆる非標準のメソッドです。

そのため、これから新しく記述するJavaScriptコードでは、わざわざsubstrを使用する理由は無いと思います。

結論:slicesubstringをお好みで

以上のことから、slicesubstringのどちらかを好みで使うというのが結論となります。他人の書いたソースコードを読む際に驚かないよう、どちらのメソッドも知識としては知っておきましょう。

細かな違いとして、slicesubstringは負の数の扱いが異なりますので、末尾からの位置を利用するケースを考えてみます。数値の前に0を加えて桁を揃える「ゼロパティング(ゼロ埋め)」処理を例に挙げると、

// 先頭を0で埋めて3桁にする

let num1 = 15;
let num2 =  8;

num1 = '000' + num1;
num2 = '000' + num2;

console.log(num1.slice(-3));  // 015
console.log(num2.slice(-3));  // 008

console.log(num1.substring(num1.length - 3));  // 015
console.log(num2.substring(num2.length - 3));  // 008

このように、結果は同じですが、sliceを使うと、より短い記述が可能となります。

応用編:開始・終了位置が不定の場合

文字列を切り出す際の位置が場合によって変わる場合、何か目印となる文字や文字列を作り、その文字や文字列の位置を調べることで、開始位置や終了位置を特定します。

使用するメソッドはindexOflastIndexOf

構文

string.indexOf(検索文字列, [開始位置])
string.lastIndexOf(検索文字列, [開始位置])
  • 開始位置を省略すると、indexOfは先頭から、lastIndexOfは末尾し銭湯からの数を返します。
  • 検索文字列が見つからなかった場合は、-1が返ります。

使用例

const string = 'hoge fuga piyo';
console.log(string.indexOf(' '));     // 4
console.log(string.lastIndexOf(' ')); // 9
console.log(string.indexOf('/'));     // -1

具体例: 電話番号を3つのブロックに分解する

ハイフンで区切られた電話番号を、3つのブロックに分解してみます。

電話番号の形式は色々ありますが、ここでは012-345-6789090-1234-5678のように、必ず-が2回入ることとします。桁数は問いません。

const p = '01-2345-6789';

// 2つのハイフンの位置を調べる
const firstPos = p.indexOf('-');
const secondPos = p.lastIndexOf('-');

// 第1ブロック:先頭から最初のハイフンまで
console.log(p.slice(0, firstPos)); // 01

// 第2ブロック:第1ハイフンの次の文字から第2ハイフンまで
console.log(p.slice(firstPos + 1, secondPos)); // 2345

// 第3ブロック:第2ハイフンの次の文字から末尾まで
console.log(p.slice(secondPos + 1)); // 6789

ハイフンが入ったり入らなかったりするなど、より複雑なパターンに対応する場合は、正規表現の利用を検討しますが、簡単な文字列の切り出しであれば、この記事で紹介したメソッドでも、十分対応することができます。