文字列の切り出し
文字列加工の基本操作として、文字列の一部分を切り出すものがある。部分文字列(substring)と呼ばれることがある。
注意点
言語、ライブラリによって、実装方法が千差万別になっていて、統一された方法が存在しない。
このため、別の言語、ライブラリを使っていた人が、うっかり間違えて使うケースが後を絶たない。
1単位の考え方が言語・ライブラリごとに違っている。
1バイト、1ワード、1コードポイント、1文字(1書記素) Unicode では複数バイト、複数ワードで1コードポイントになる事がある。
Unicode では複数コードポイントで1書記素になる事がある。
人間が文字として認識する単位(書記素)と、文字コードの基本単位とがずれているため、ほとんどの場合、単純に「n文字」とはならない。 Unicode での書記素クラスタ(graphme cluster)について書かれている。
データベースの文字数はコードポイント数になっていることが多い。
先頭の位置を0とするものと1とするものとがある。(特に要注意)
ライブラリによってぶれているケースもあるので要注意。
{開始位置、終了位置}型と、{開始位置、長さ}型がある。混同されやすい。
終了位置型の場合、終了位置を含む場合と含まない場合がある。混同されやすい。
(「2から3」とした時、2のみ取れるか、2と3が取れるかの違いがある。)
指定位置が文字列の範囲をはみ出した時に、エラーとするものと、そのまま可能な限り合理性を保って処理するものとがある。
はみ出した場合、主に、空白で置き換えるものと、空文字列で置き換えるものとがある。
マイナス位置は、終端からの位置とみなすものがある。
開始位置と終了位置が逆転した時、以下のようなパターンが考えられる。
エラーとする
再逆転させて範囲とみなす
文字列を逆転させて抜き出す
空文字列とする
ここを見る前に先に見るべきもの
awk
substr(文字列, 開始位置, 文字数)
先頭は1
C言語
通常、先頭は0
char なら実質バイト単位
wchar_t は UCS-2, UTF-16, UTF-32 のどれかになっている事が多い。
標準ライブラリには、直接的な関数は用意されていない。
文字列はバイト配列なので、memcpy や strncpy で切り出すのがよく使われる。
JavaScript
先頭は0
文字列.substring(開始位置[, 終了位置])
開始位置から終了位置(それ自身を含まない)までの切り出し(終了位置はオプション)
範囲がはみ出してもエラーにはならず、空文字列として取り出される。(空白ではない)
文字列.slice(開始位置[, 終了位置])
負数を使うと後方を起点としたインデックスになる。
範囲がはみ出してもエラーにはならず、空文字列として取り出される。(空白ではない)
substr
非推奨。使うべきではない。
文字列.substr(開始位置, 長さ)
substring, slice とは異なり、引数の2つ目は「長さ」なので、関数名を置換するだけだと壊れる。必ず計算し直すこと。
文字列.substring(開始位置, 開始位置+長さ)にすれば良い。
参考
絵文字の中には国コードの組み合わせた国旗、バリエーションセレクターが後ろに続く異体字 (バリアント)、肌色を変える修飾子が続くもの (Unicode 8.0 で導入予定) など、2つのコードポイントで構成されるものもあるので、それらも考慮する必要がある場合、拡張書記素クラスターに対応したライブラリが必要になります。
Java
先頭は0
String#substring
範囲がはみ出ると例外。
VBA
先頭は1
Mid 関数が使われる。
先頭からなら Left 関数
末尾からなら Right 関数
シェルスクリプト
標準SQL
SUBSTRING( 文字列 FROM 位置 [ FOR 長さ ] )
先頭は1
カウントは文字数(文字の数え方は実装依存である事に注意)
しかし、この通り実装しているデータベースがほとんどない。
PostgreSQL OK
PostgreSQL
SUBSTR( 文字列, 開始位置[, 長さ] )
先頭は1
非標準
Rust
Keyword: 文字列,範囲,切り取り,抜き出し,部分文字列の取得