正規表現(4) 検索オプション /m

他にも色々な検索オプションがあります。

正規表現の中で「^」(サーカムフレックス)と「$」(ドル記号)はそれぞれ「文字列の先頭」「文字列の末尾」という意味を持っています。

use strict;
 
$_ = "One Two Three Four Five";
print "$_\n";
 
print (/^One/   ? "o" : "x");  # 先頭の One
print (/One/    ? "o" : "x");  # One
print (/One$/   ? "o" : "x");  # 末尾の One
print " One\n";
 
print (/^Three/ ? "o" : "x");  # 先頭の Three
print (/Three/  ? "o" : "x");  # Three
print (/Three$/ ? "o" : "x");  # 末尾の Three
print " Three\n";
 
print (/^Five/  ? "o" : "x");  # 先頭の Five
print (/Five/   ? "o" : "x");  # Five
print (/Five$/  ? "o" : "x");  # 末尾の Five
print " Five\n";

「A ? B : C」は A が真なら B を、偽なら C を返す「三項演算子」と呼ばれる演算子です。また、検索対象の文字列を指定せずに正規表現を記述すると、$_ が検索対象となるのでした。
つまり (/検索パターン/ ? "o" : "x") は検索パターンが $_ の一部にマッチすれば "o" が、マッチしなければ "x" が返ってきます。
実行結果です。

One Two Three Four Five
oox One
xox Three
xoo Five

「/m」オプションを使うと、この「^」と「$」がそれぞれ「行頭」「行末」(改行文字 \n の後ろと前)にもマッチするようになります。これにより、複数行の文字列からの検索がとっても簡単になります。

m/^apple/m;   # 行頭にある apple にマッチ。
m/lemon$/m;   # 行末にある lemon にマッチ。
m/^grape/im;  # 行頭にある grape にマッチ。大文字小文字を区別しない。
              # このように複数のオプションも指定可能。
              # オプションの順番は特に関係ない。 

早速使ってみます。

use strict;
 
my $text = "I LOVE A FRESH APPLE SO MUCH!
An apple pie and banana juice as well.
They are so lovely.";
print "$text\n\n";
 
my @patterns = (
    'banana juice', '^banana juice',
    'An apple',     '^An apple',
    'lovely\.',     'lovely\.$',
);
 
for my $pattern (@patterns) {
    printf "%-15s", $pattern;
    print ($text =~ /$pattern/im ? "o\n" : "x\n");
}

@patterns に入れた正規表現を $text に対して順番に適用しています。
printf は書式付きで出力できる関数です(C言語のものと同じです)。「printf "%-15s", $pattern;」は、$pattern を文字列として左詰め・幅15で出力します。文字列の幅が足りない場合は空白で埋められます。書式について詳しくは「perldoc -f sprintf」などをご覧ください。
実行結果です。

I LOVE A FRESH APPLE SO MUCH!
An apple pie and banana juice as well.
They are so lovely.

banana juice   o
^banana juice  x
An apple       o
^An apple      o
lovely\.       o
lovely\.$      o

「^An apple」は通常、文字列の先頭の An apple にしかマッチしませんが、「/m」オプションを付けた事で、2行目の行頭にある An apple にマッチしています。

複数行の文字列は扱う機会が多いはずですので、「/m」オプションは知っておくと便利ですね。(^_^)