正規表現の区切りで文字列を分割する
split
は、文字列 EXPR を、正規表現 /PATTERN/ に一致する文字列で分割し、
それらをリストとして返します。
EXPR が省略された場合は $_ が適用されます。
次のサンプルコードは |
およびその前後のスペースで文字列を区切ります。
my $str = 'Taro | Jiro | Saburo';
my @names = split /\s*\|\s*/, $str;
print join( ', ', @names ); # Taro, Jiro, Saburo
もし正規表現 /PATTERN/ に一致する文字列が 文字列 EXPR の最後に連続して現れる場合、 それらは削除されたうえで分割されます。
my $str = "Taro | Jiro | Saburo | | | ";
my @names = split /\s*\|\s*/, $str;
print join( ', ', @names ); # Taro, Jiro, Saburo
正規表現 /PATTERN/ には空文字列を入れることができます。 その場合は、EXPR の文字を一文字つずに分割することになります。 日本語を扱う場合は、EXPR の文字列は内部文字列でなければいけませんので注意してください。
use utf8;
binmode STDOUT, ":utf8";
my $str = 'あいうえお';
my @chars = split //, $str;
print join( ', ', @chars ); # あ, い, う, え, お
正規表現 /PATTERN/ の部分を文字列で指定することもできます。 しかし、半角スペースを指定した場合は、やや特殊な挙動が見られるので注意が必要です。
次のサンプルコードは、半角スペースとタブを含んだ文字列を、
文字列の半角スペース " "
で区切ります。
分割の状況を分かりやすくするために、結果として得られた配列をカンマとスペースで連結し、
その全体を [ ]
で囲んでいます。
my $str = " a\tb c \t";
my @parts = split ' ', $str;
print '[' . join( ', ', @parts ) . ']'; # [a, b, c]
結果をご覧の通り、文字列の前後のスペースやタブは削除され、 そして、文字列の中に現れる連続して現れるスペースは一つにまとめられたうえで分割されたことが分かります。 さらに、スペースだけでなく、タブも分割文字として使われていることが分かります。
なお、これを正規表現 / /
で区切ると、期待通りに、事前に何もせず、純粋に半角スペースだけで区切ります。
my $str = " a\tb c \t";
my @parts = split / /, $str;
print '[' . join( ', ', @parts ) . ']'; # [, , a b, , c, ]
なお、この文字列の半角スペース " "
を区切りに指定した場合、
半角スペースやタブだけでなく、日本語であれば全角文字列も対象になります。
use utf8;
binmode STDOUT, ":utf8";
$_ = " 太郎 次郎 三郎 ";
my @names = split;
print join( ', ', @names ); # 太郎, 次郎, 三郎
このように正規表現 /PATTERN/ の部分に文字列の半角スペース " "
を指定する場合、
挙動を分かったうえで使うのであれば便利になる場合もあるでしょうが、
知らずに使うと期待通りの結果になりませんので注意が必要です。
もし、EXPR だけでなく /PATTERN/ も省略された場合は、
EXPR に $_ が、/PATTERN/ に " "
が指定されたものとして処理されます。
つまり、split(' ', $_)
と同じです。
$_ = "\tTaro\tJiro\tSaburo\t";
my @names = split;
print join( ', ', @names ); # Taro, Jiro, Saburo
split
は第三引数 LIMIT を指定することができますが、これは分割最大数を意味します。
たとえば LIMIT に 1 を指定すると分割されません。
2 を指定すると、たとえ結果は 3 分割以上になろうとも、最初の 2 つしか分割されません。
my @names1 = split //, 'abc', 1;
print join( ', ', @names1 ), "\n"; # abc
my @names2 = split //, 'abc', 2;
print join( ', ', @names2 ), "\n"; # a, bc
my @names3 = split //, 'abc', 3;
print join( ', ', @names3 ), "\n"; # a, b, c
もし LIMIT に負の整数を指定すると、指定しなかった場合と同様に分割数の上限は無くなりますが、 最後に区切り文字が連続していた場合に、それらを削除することはせず、その部分は空文字列の要素として分解されます。
my $str = 'a|b|c||||';
my @parts1 = split /\|/, $str;
print join( ', ', @parts1 ), "\n"; # a, b, c
my @parts2 = split /\|/, $str, -1;
print join( ', ', @parts2 ), "\n"; # a, b, c, , , ,