部分文字列

文字列の一部を抽出する処理。slice、substring、substr などのメソッドで取得する。

部分文字列 (Substring) とは、元の文字列から一部分を抽出して得られる文字列のことです。テキスト処理やデータ解析で頻繁に使用される基本操作であり、ファイルパスからファイル名を取り出す、URL からドメインを抽出する、ログメッセージから日時部分を切り出すなど、実務のあらゆる場面で活用されます。

JavaScript では slice()substring()substr() の 3 つのメソッドが利用できます。slice(start, end) は負のインデックスに対応し、末尾からの位置指定が可能なため最も汎用的です。substring(start, end) は引数が負の場合に 0 として扱い、引数の大小を自動的に入れ替えます。substr(start, length) は第 2 引数が長さを表しますが、ECMAScript 仕様では非推奨とされています。実務では slice() を使うのが最も安全です。JavaScript 文字列操作の書籍で各メソッドの違いを学べます。

Python では str[start:end] のスライス記法が標準的です。str[2:5] でインデックス 2 から 4 までの 3 文字を取得し、str[-3:] で末尾 3 文字を取得できます。ステップ指定 (str[::2]) を使えば 1 文字おきの抽出も可能です。Java では substring(beginIndex, endIndex) メソッド、Go では str[start:end] のスライス構文が使われます。

Unicode 文字列から部分文字列を抽出する際は、サロゲートペアや書記素クラスタの境界に注意が必要です。JavaScript の slice() は UTF-16 コードユニット単位で動作するため、絵文字やサロゲートペア文字の途中で切断すると不正な文字列が生成されます。正確に文字単位で切り出すには [...str].slice(start, end).join('') のようにスプレッド構文でコードポイント単位に分解してから操作する方法が有効です。

よくある誤解として、部分文字列の抽出が常に新しい文字列を生成するという思い込みがあります。Java の旧バージョン (Java 7 update 6 以前) では substring() が元の文字列の内部配列を共有していたため、短い部分文字列を保持するだけで巨大な元文字列がガベージコレクションされないメモリリークが発生していました。現在の Java では新しい配列がコピーされるため、この問題は解消されています。

文字数カウントの観点では、部分文字列の長さは end - start で計算できますが、マルチバイト文字を含む場合はバイト数と文字数が一致しません。たとえば UTF-8 で「東京タワー」の先頭 2 文字を抽出すると文字数は 2 ですが、バイト数は 6 (1 文字あたり 3 バイト) になります。文字数制限のあるフォームやデータベースカラムに部分文字列を格納する際は、文字数とバイト数の両方を確認することが重要です。テキスト処理プログラミングの書籍で言語ごとの部分文字列操作を比較できます。