pos

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 を返します。 もし上記コードでもう一度同じ正規表現で検索を実行すると、posundef を返します。 posundef を返したとき、それは検索位置がリセットされたことを意味します (通常は検索失敗によるものですが、スカラー上で検索がまだ走っていない場合も起こりえます)。

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