substr

文字列の一部を取得または変更する

構文

解説

substr は、引数の文字列 EXPR から部分文字列を抽出して、それを返します。 部分文字列は文字列 EXPR の位置 OFFSET から数えて LENGTH 文字分になります。 LENGTH が省略されたら EXPR の最後までが対象になります。 LENGTH に負の数値が指定されたら、EXPR の最後から数えた位置を終了位置とします。

my $str = 'Perl is great.';
print substr $str, 5;        # "is great."
print substr $str, 5, 2;     # "is"
print substr $str, 0, -3;    # "Perl is gre"
print substr $str, -6;       # "great."
print substr $str, -6, 5;    # "great"

日本語などのマルチバイト文字を扱う場合は、utf8 フラグが ON の内部文字列を使ってください。 もし utf8 フラグが ON でない外部文字列を substr で扱うと、 バイト単位で処理されてしまい、期待通りの結果になりません。 次の例は utf8 フラグが ON でない日本語を扱った場合の例です。

my $str = 'あいうえお';
print substr $str, 3; # "いうえお"

本来であれば 3 文字目以降の部分文字列「えお」が得られると期待しますが、実際には「いうえお」が得られてしまいます。 これは、このソースコードが UTF-8 で「あ」は UTF-8 でたまたま 3 バイトだったためです。 日本語を期待通りに扱うのであれば、use utf8 プラグマを宣言するなどして、 utf8 フラグが ON の内部文字列にして処理してください。

use utf8;
binmode STDOUT, ":utf8";

my $str = 'あいうえお';
print substr $str, 3; # "えお"

substr は、4 番目の引数 REPLACEMENT を指定することで、 部分文字列を別の文字列に置換する機能もあります。 このとき、substr は置き換わる前の文字列を返します。 この点は splice と同じです。 次の例では、文字列「吾輩は猫である」のうち、最後の「猫」を「子犬」に置換しています。

use utf8;
binmode STDOUT, ":utf8";

my $string   = "吾輩は猫である";
my $replaced = substr $string, 3, 1, "子犬";

print $string,   "\n";    # 吾輩は子犬である
print $replaced, "\n";    # 猫

substr は左辺値として扱い、値を代入することができます。 この代入する値は 4 番目の引数 REPLACEMENT に相当します。 次の例は、前述の文字列置換と同じことをしています。

use utf8;
binmode STDOUT, ":utf8";

my $string = "吾輩は猫である";
substr( $string, 3, 1 ) = "子犬";

print $string, "\n";    # 吾輩は子犬である

もし substr を左辺値として扱った際に 3 番目の引数 LENGTH を指定しなかった場合は、 右辺に指定した文字列を指定位置に挿入し、それ以降は切り取られます。

use utf8;
binmode STDOUT, ":utf8";

my $string = "吾輩は猫である";
substr( $string, 3 ) = "子犬";

print $string, "\n";    # 吾輩は子犬