m//g 検索位置を取得またはセットする
pos
は、対象の変数 SCALAR に対して正規表現 m//g
(//g
)
による検索が最後に終了したオフセット位置を返します。
SCALAR が省略されたら $_ が適用されます。
オフセット位置の単位は、use bytes
(現在は非推奨)
が有効ならバイト数ですが、そうでない限り、文字数です。
次のコードは、文字列 "01234567890123456789" から "01" を 2 回検索しています。
my $str = '01234567890123456789';
$str =~ /01/g;
print pos($str), "\n"; # 2
$str =~ /01/g;
print pos($str), "\n"; # 12
上記コードの結果の通り、正規表現のマッチングが成功すると、pos
はマッチの終点のオフセット位置を返します。
つまり、"01" はオフセット 0 と 10 の位置を始点として存在しますが、pos
は終点となる 2 と 12 を返します。
もし日本語を扱う場合は、use utf8
を使って utf8 モードを有効にしてください。
そうしないと、文字数でカウントされませんので注意してください。
use utf8;
my $str = 'あいうえおあいうえお';
$str =~ /あい/g;
print pos($str), "\n"; # 2
$str =~ /あい/g;
print pos($str), "\n"; # 7
pos
は正規表現による検索で対象が見つからないと undef
を返します。
もし上記コードでもう一度同じ正規表現で検索を実行すると、pos
は undef
を返します。
pos
が undef
を返したとき、それは検索位置がリセットされたことを意味します
(通常は検索失敗によるものですが、スカラー上で検索がまだ走っていない場合も起こりえます)。
pos
は検索文字列の終点のオフセット位置を返すことを考えると、0 が返されることはないと思うかもしれませんが、
次のようなコードなら pos
は 0 を返します。
$str =~ //g;
print pos($str), "\n"; # 0
従って、上記コードのような空文字列の正規表現が使われる可能性があるなら、
pos
の戻り値を if
などで評価するのは適切ではありません。
もし評価するなら defined
を使うのが良いでしょう。
if ( defined( my $offset = pos($str) ) ) {
# 検索がヒットしたときの処理
}
pos
を使って正規表現の検索開始位置をセットすることもできます。
次のコードは pos
を左辺として 3 を代入しています。
これによって正規表現の検索開始位置を 3 文字目に移動します。
次の正規表現では 3 文字目以降から検索が行われることになります。
use utf8;
my $str = 'あいうえおあいうえお';
pos($str) = 3; # 検索位置を 3 文字目に移動
$str =~ /あ/g; # 3 文字目以降から「あ」を検索
print pos($str), "\n"; # 6