Perlのアレコレ



1. 言語としてのコンセプトの違い

bash と Perl はスクリプト言語(インタプリタで実行)としては同じですが、そのコンセプトには大きな違いがあります。bash と Perl には以下のようなコンセプトの違いがあります。

bash Perl
様々なパーツ(コマンドとして実装されているもの)を組み合わせてひとつのものを作る Perl 自身で何でもできるように設計されている
文字列に対する処理が貧弱(awk,sed (もちろん Perlも!)の力を借りないと何もできない) 文字列に対する処理は既存の言語の中でも最強
実数演算ができない(整数のみ) ごく普通
bash 自体の拡張性がない(利用するコマンドの限界が bash としての限界) The Possibilities are infinite!

結論からいえば、bash にできて Perl にできないことはありません
これは極論かもしれませんが、bash はファイル操作のみに重きをおいています。ですから、扱う単位がファイル単位です。つまり「このファイルの中に test という文字列があったら」という条件分岐ではなく、「このファイルのパーミッションがこうだったら」「このファイルの更新日時がこうだったら」のような扱いをすることになります。
bash における処理対象がこのようなものであることから、ファイルの中身をいじるようなプログラムは bash 単体では難しいということが分かってもらえると思います。


2. 文字列処理における最強の手段 〜〜〜 正規表現 〜〜〜

1章でも述べたように bash の主な使用目的はファイル単位の操作です。サンプルプログラムのほとんどもファイル操作です。
cut コマンドを使った CSV ファイルの処理は行いましたが、あくまでも ReadOnly でした。文字列の置換を行うような作業は bash ではできません。
「ファイルの中身をいじるかいじらないか」というのは、bash と Perl の使い分けの大事なポイントになります。


一般に人間が見たい、もしくは、見る必要があるファイルというのは文字列の集合です。つまりファイルをいじる = 文字列を処理する、ということを意味します。

前置きが長くなりましたが、文字列を処理する上で「正規表現」という特定の文字列に対してだけマッチするような、文字列表現の集大成があります。正規表現を一言でまとめるのは難しいですが、簡単な例を示すので感じだけ掴んでください。



2.1 正規表現のコア、「メタ文字」

ワイルドカードという言葉を聞いたことがあると思います。シェルで ls a* とすれば、a から始まるファイル名だけを表示する、というような使い方をしていると思います。メタ文字とはまさにこの * のことです。

正規表現における簡単なメタ文字を紹介します。


このようなメタ文字を使って特定の文字列だけを入手することが出来します。流行りの XML などの処理にも正規表現は絶大な力を発揮します。
例えば、50MBもある XML ファイルから、<IMPORTANT> </IMPORTANT> の間の文字列だけを抜粋するような処理も、Perl と正規表現を使えば以下のように簡単にできます。
open FILE , 'target.xml'; @_ = <FILE>; close FILE; foreach (@_) { print $1 if /<IMPORTANT>(.*?)<\/IMPORTANT>/g; }
プログラム2.1


表示させるだけなら grep コマンドで出来ます。ここまでは実は bash でもがんばればできることです。

では、こんなのはどうでしょう。
歳を取ってきて、小さい字が読めなくなって来た。HTML の <FONT> タグで SIZE="+1" や SIZE="-3" となっているのを SIZE="+3" に全部変えたい。手作業でやれといわれたら泣きたくなるような作業です。bash でやろうと思っても、説明したように文字列の置換は bash ではできません。しかし、Perl ならこんなに簡単です。
open FILE , 'source.html'; @_ = <FILE>; close FILE; foreach (@_) { s/SIZE="(\+|-)\d"/SIZE="+3"/ig; } open FILE , '>convert.html'; print FILE @_; close FILE;

プログラム2.2

SIZE="(\+|-)\d" の部分が正規表現です。
このように正規表現は、文字列中のパターンを独自のメタ文字とリテラル(メタ文字と違って、ある特定の一つの文字列にのみマッチする)によって表現することができます。
きっちりとマッチさせたい部分はリテラルで表記し、それ以外をメタ文字で表記します。上の例の場合、HTML ファイル中に「SIZE=」という文字は必ずある文字列です。その後に続く "+N" の部分はどうでもいいものです(元々していされているフォントサイズとは無関係に、すべて3にしたい)。 \d というのは数字にマッチするメタ文字です。つまり SIZE="+1" でも SIZE="+8" でも上の正規表現ならばマッチします。
SIZE="+3" の部分は置換後の文字列です。
s/// は、/ に囲まれた最初のフィールドに書かれた正規表現にマッチする部分を、次のフィールドに書かれている文字列置換する演算子です。仮に元の HTML に <FONT SIZE="+1">test</FONT> と書かれていたとすると、SIZE="+1" の部分に正規表現がマッチし、その部分が SIZE="+3" に変わります。
これが Perl における 正規表現の使い方です。



2.2 ゴキブリの大群 ---エスケープ---

2.1 節で書いた正規表現をみれば分かるように、\ が2回登場しています。
プログラミングを経験したことがある人ならエスケープの意味が分かると思います。正規表現におけるエスケープは、メタ文字のパワーを奪いさる役目をします。. と書けば何にでもマッチする最強のメタ文字 . が \. と書かれた瞬間に「ただの . 」 になってしまいます。

Perl の正規表現中でエスケープしなければいけない文字は以下の通りです。
「 . 」 , 「 * 」 , 「 + 」 , 「 \」 , 「 ( 」 , 「 ) 」 , 「 [ 」 , 「 ] 」 , 「 { 」 , 「 } 」 , 「 / 」 , 「 ? 」 , 「 ^ 」 , 「 | 」 , 「 $ 」 , 「 @ 」
多いです。記号文字がほとんど対象になります。逆に、エスケープしなくてよい文字を覚えるほうが幸せになれるかもしれません。


3. Perl における基本事項

Perl はその柔軟性から、C などのガチガチの言語に比べて比較的自由なコーディングスタイルをとることができます。

3.1 基本的な文法

Perl における文法は、C におけるそれと酷似しています。文の終わりはセミコロン、{} によるブロック構造など C プログラミングが分かる人ならば直感的に理解できるでしょう。
大きな違いはコメントです。C では /* */ でくくられている部分がコメントになりますが、Perl では(スクリプト言語という位置付けから)コメントは # で行います。# から行末までがコメントとみなされます。
print 1+1; #here is comment-out
となります。

"test" , 'test' はともに文字列 test を表しますが、"" 中では変数展開が行われ、'' 中では行われません。また、'' 中では、エスケープシーケンスも無視されます。
変数に関してはまだ触れていませんが、
$string = 'test';
print "$string"; # test が出力
print '$test'; # $test という文字列を出力
という扱いになります。


3.2 変数

Perl における変数は「無制限可変長変数」です。また型はありません。つまり数値でも文字列でもなんでも格納することが出来ます。
Perl では変数にアクセスする際、頭に $ をつけます。これは bash で変数を参照するときと同じです。
Perl は変数を宣言しなくても使えますが、タイプミスなどの無駄なバグの混入を防げるので、宣言することをおすすめします。

宣言していない変数の使用を防ぐには、Perl スクリプトの最初の方に
use strict;
と書くことで、Perlが自動的に変数の宣言のチェックを行ってくれます。

my $test
とかけば、test という名前の変数を使用することが出来ます。変数の取り扱いとしては他の言語と変わりありません。
#変数に値を代入
my $test;
$test = 1;
#文字列を代入
$test = "test";

Perl の変数に型がないのは、Perl 自身で変数の使い分けを行えるからです。関数や演算子の対象となっている変数の中身(具体的には数値か文字列か)を吟味し、その時々によって変数の内容を解釈してくれます。以下に具体例を示します。
my $string = "1.1";
my $num = 1.5;
print $string + $num;
結果は 2.6 が出力されます。文字列としての "1.1" と数値の 1.5 を + 演算子の対象にした場合、$string という変数に格納されている文字列を数値と解釈して $num に格納されている数値 1.5 と加算してその結果を返します。


3.3 配列

Perl での配列を理解する前に「リスト」という概念を理解しなければいけません。言葉で説明するのが難しいので以下に例を示します。

($var1 , $var2 , $var3) = (1 , 2 , 3);
このカッコでくくられたものがリストです。何とも表現しにくいですが、() でくくられ、カンマで区切られている値(変数)をグループ化したものだと考えてください。
上の例では、$var1 に 1 、$var2 に 2 、$var3 に 3 が代入されます。配列は $var1 、$var2 、 $var3 を要素番号で関連づけたものです。
Perl で配列を表す記号は @ です。@a は配列a を表します。配列を使用するには変数と同じく my で宣言してやります。
my @array;
@array = ("first" , "second" , "third");
print $array[0]; #first
print $array[1]; #second
print $array[2]; #third
上の例を見れば分かるように、配列の各要素にアクセスするには $配列名[要素番号]という書き方になります。配列の記号は @ なのに、要素を表すときには $ を使う、というのは分かりにくいですが、この記号の使い方は「$ はスカラーを表す」という Perl の記号仕様理念に基づいているものです。

複数個の変数を一つの配列にまとめたい場合も、リストの概念が分かっていれば簡単に出来ます。
my $arg1 , $arg2 , $arg3;
$arg1 = "first";
$arg2 = "second";
$arg3 = "third";
my @array;
@array = ($arg1 , $arg2 , $arg3);

配列同士のコピーも @to = @from とすることで、簡単に行えます。


3.4 ハッシュ

Perl でのハッシュは日本語で「連想配列」と訳されます。連想、というように、何かキーワードがあって、それに対応する値を格納するのがハッシュの役目です。ハッシュを表す記号は % です。%hash は hash という名前のハッシュを表します。

my %myself;
%myself = ('name'=> 'Ryo SHIMIZU' , 'age' => 21);
print $myself{name}; #Ryo SHIMIZU
print $myself{age}; #21

のような感じで使います。name というキーワードに対して 'Ryo SHIMIZU' という値があり、age というキーワードに対して 21 という値があります。
最初のうちは有効な使い方が分からないかもしれませんが、キーワードに関連づけて値を格納することができる、というのは直感的に分かりやすい部分があります。

ハッシュのキーワードのことを「キー」と呼びます。またキーに対応する値のことを「バリュー」と呼びます。
ハッシュのキーの部分を表記するのに変数を使うこともできます。

my %myself = ('name' => 'Ryo SHIMIZU' , 'age' => 21);
my $val1 = 'name';
my $val2 = 'age';
print $myself{$val1}; #Ryo SHIMIZU
print $myself{$val2}; #21

$myself{$val1} と書くことで、変数 $val1 が変数展開され文字列の name となります。よって、$myself{$val1} は $myself{'name'} と書いたのと同じことになります。


3.5 名前空間

Perl では、変数、配列、ハッシュの三つのタイプがありますが、それぞれの名前はすべて独立しています。つまり、
my $test
my @test
my %test
と、test とおいう名前の変数、配列、ハッシュを宣言することはエラーにはなりません。Perl がそれぞれの名前空間を用意しているため、たとえ変数と配列に同じ test という名前が付いていても、そこでバッティングが起こることはありません。

しかし、@test という配列の最初の要素を表すには $test[0] と書くので、人間にとって、変数としての $test と混同する恐れがあります。変数、配列、ハッシュのそれぞれに同じ名前をつけることは可能ですが、ソースの可読性を上げるならばそれをしない方がよいです。


4. 演算子、制御文

4.1 演算子

Perl における演算子は C 言語とほぼ同じです。Perl 特有の演算子のみ説明します。
○数値に対する演算子

**
累乗演算子です。対象となる変数の累乗を返します。

== , !=
数値における等価演算子です。

○論理演算子

&& , ||
論理積、論理和です。and 、 or で書き換えが可能です。つまり
$arg1 && $arg2

$arg1 and $arg2
で書き換え可能です。

○文字列に対する演算子

eq , ne
文字列における、等価演算子です。
. (ドット)
文字列を連結する演算子です。$string = "a" . "b"; とした場合、$string には "ab" が格納されます。

x (アルファベットのエックス)
繰り返し演算子です。$string = "a" x 5; とした場合、$string には "aaaaa" が格納されます。

○その他の演算子

.. (ドットドット)
範囲演算子と呼ばれます。VBA の to と同じ役割をします。@array = (1 .. 5); とした場合、@array には 1 2 3 4 5 が格納されます。

=~ , !~
拘束演算子と呼ばれます。正規表現を使う際に用います。詳しくは文字列操作の章で説明します。

<>
ダイアモンド演算子と呼ばれます。ファイルハンドルを扱う際に用います。詳しくはファイル操作の章で説明します。


4.2 制御文

Perl における制御文は C とそう変わりはありません。しかし、foreach という特殊な制御文があるため、おそらく for 文を使う機会はあまりないでしょう。


5. 関数および変数のスコープ

Perl には C でいう main 関数にあたるものが見た目上ありません。サブルーチン以外の部分はすべて仮想的に main 関数に対応づけられます。
この章では、Perl における関数(サブルーチン)の使い方と、それに伴う変数のスコープについて説明します。


5.1 関数の定義

Perl では以下のようにサブルーチンを定義、呼び出しします。
#main 関数

print "in the main\n";
&func;

sub func
{
  print "in the func\n";
}

プログラム5.1
この実行結果は、
in the main
in the func
となります。サブルーチンを定義する際は sub FUNC_NAME{ ... } という構文になります。また、その関数を呼び出す際は、関数名の頭に & をつけることにより可能です。
Perl では関数呼び出しの際に () は必要ありません。もちろん () をつけてもきちんと動作します。() をつけるかどうかは、個人のコーディングスタイルによるものなので、どちらでも構いません。ただ、引数を取る関数の場合は、どこまでが引数かを明確にしてやるために、() をつける必要があります。


5.2 引数をとる関数の定義および変数のスコープ

通常、関数は引数をとって、その値をパラメータにして処理内容が変わってきます。C などの言語では、関数が引数を取る際、「仮引数」というものを定義しなければいけません。しかし強力な変数管理能力を持つ Perl にはそんなものは必要ありません。
サブルーチンが受け取る引数は、@_ という特殊な配列に格納されています。7章 にも書きましたが、@_ は特殊な配列で、スクリプト中においてグローバルで、どこからでも参照することができます。以下に引数を取るサブルーチンの例を示します。
#main 部分
my $arg1 = 1;
my $arg2 = 3;
my $recv_value = &plus($arg1, $arg2);
print $recv_value;

#main 終わり

sub plus
{
  my $get1 = $_[0];
  my $get2 = $_[1];
  return($get1 + $get2);
}

プログラム5.2

さて、このサブルーチン plus が何をやっているかというと、二つの引数をとり、その二つの和を返しています。main 部分から渡された二つの引数は @_ に格納されています。二つの引数を格納する変数 $get1 , $get2 にはそれぞれ $_[0] , $_[1] を代入してやります。これが引数をとるサブルーチンの使い方です。
仮引数という存在がないおかげで、関数がとる引数を簡単に可変長にすることができます。引数をすべて受け取るための配列 @arg を用意してやって、@arg = @_; とすることで、引数すべてを @arg に格納することが出来ます。あとはすばらしい foreach 構文を使って処理をすれば完璧です。
引数を取る関数といっても、引数が @_ に格納されているという以外、なにも特殊なことはありません。また、より Perl らしい書き方をすれば、plus 関数の1行目は
my(get1 , get2) = @_;
のようになります。

plus 関数では $get1 , $get2 という二つの変数がありますが、この二つの変数は plus 関数の中でのみ有効なものです。
my で宣言した変数はレキシカル変数といい、変数として有効な範囲が明確に定められています。C++ でも
for(int i=0;i<10;i++)
{
printf("%d\n" , i);
}

のように、for 文のブロック中でのみ有効な変数 i を宣言することができますが、Perl での my 宣言はそれと同じ意味を持ちます。このことをより理解するための例を以下に示します。
#main 部分
my $test = 1;
print $test , "\n";  # 1が出力される
&hoge;          # 2が出力される
print $test , "\n";  # 1が出力される
sub hoge
{
  my $test = 2;
  print $test , "\n";
}
プログラム5.3
main 関数と hoge 関数の両方で $test という変数を使っていますが、これら二つの変数は独立しています。よって、hoge 関数の中で $test の値を 2 にしても、それは main 関数での $test にはまったく関係ないのです。

最後に return 文の説明をします。Perl での return 文は何でも返すことが出来ます。C では return が返す値は一つしか許されません。よって構造体とポインタを駆使してなんとか希望するデータを関数から受け取っていましたが、Perl ではそんな悩みは無用です。
return の返す値としてリストを用いることで、いくつもの値を返すことができます。また、リストが返せるということは、もちろん配列も返せますし、ハッシュを返すこともできます。
上に書いた足し算の結果を返す関数 plus も、最後の return 文を以下のようにすることで、足し算の途中過程(何と何を足したか)を明確にすることができます。
return ($get1 , $get2 , $get1+get2);


Perl の強力な変数管理(メモリ管理)とリストという柔軟な型のおかげで、Perl でのサブルーチンというのはこのように扱いやすくなっています。


6. Perl の真骨頂「正規表現」

この章では正規表現および、正規表現を利用した文字列処理を説明していきます。


6.1 いかなる文字列であろうとマッチさせる!

2章で軽く触れたように、正規表現にはリテラルとメタ文字という2種類の道具を使って、文字列を表現します。リテラルとは自分自身にのみマッチするものです。メタ文字というのは、特定の文字(複数種類)にマッチするものです。メタ文字については軽く説明済みなので、感じだけはつかんでもらってると思います。

Perl では /test/ とかけばそれが正規表現になります。ここでは test が正規表現です。演算子の章で説明しましたが、正規表現がマッチしたかどうかは =~ 演算子を使って評価することが出来ます。Perl で正規表現を使う際に、どんな流れでコードを書くのかを分かってもらうために下にサンプルを示します。
$string = "this is test";
if($string =~ /test/)
{
  print "match";
}

プログラム6.1
これが Perl での正規表現の基本の書き方です。$string には "this is test" という文字列が格納されています。その変数 $string に対して /test/ という正規表現を当てはめています。/test/ と表記された正規表現は、$string の中に "test" という文字列が含まれている、ということを意味します。この test がリテラルです。つまり、文字列としての "test" にしかマッチしません。

リテラルは厳密なマッチを行うために、標準で大文字小文字の区別をします。つまり /test/ は "Test" にはマッチしません。そこで、大文字小文字の区別をなくすには /test/i と書きます。最後のスラッシュの後に i (たぶん ignorecase) をつけることで、大文字小文字の区別をなくすことができ、/test/i は "Test" にも "tEsT" にもマッチします。



Perl での正規表現の使い方、リテラルの意味は理解できたと思います。では次にメタ文字について説明します。
2.1 節で 「 . 」 , 「 * 」 , 「 + 」 の3種類のメタ文字について紹介しました。* と + の使い分けが難しいところですが、通常は + を使っていれば問題はないでしょう。

. * + の他にもメタ文字は存在します。以下にメタ文字とその意味を列挙します。
メタ文字意味
\d数字
\w英数字と下線
\n改行
\s空白文字(具体的には ホワイトスペース、タブ、改行)
\tタブ
\d+1文字以上の数字
\w+単語
$行の終わり

これらのメタ文字を使って、特定の文字列パターンを表現することができます。
例えば、CSV ファイルで、以下のような物品の納入書があるとします。
3/15,プリンタ,2,29800yen(フォーマットが日付,品名,個数,金額となっている)
このフォーマットがきっちりと守られているかどうかを以下の正規表現でチェックすることができます。

$input = "3/15,printer,2,29800yen";
if($input =~ /\d+\/\d+,\w+,\d+,\d+yen/)
{
  print "正しいフォーマット\n";
}
else
{
  print "間違ったフォーマット\n";
}
プログラム6.2

この正規表現がちゃんと読めるでしょうか?
まず、最初のフィールドは日付なので 「数字/数字」 という文字列でなければいけません。数字にマッチするメタ文字は \d ですので、\d を使います。ただ、\d だと数字1文字にしかマッチしないので、これじゃダメです。よって、1回以上の繰り返しである + を使います。よって \d+ が数字列を表す正規表現であることが分かったと思います。
数字が / で区切られていることを表現するためには \d+/\d+ と書きます。でも、/ は Perl において、正規表現の終わりを示す文字として使っているので、このままではダメです。ゴキブリを思い出してください。/ はエスケープしてやらなければいけません。
これらのことをすべて踏まえた上で、数字/数字 という日付を正規表現で表すには
\d+\/\d+
と書くことが分かったと思います。

\d+\/\d+ の後のカンマはリテラルです。カンマはメタ文字ではないので、そのままカンマとして書きます。

次の品名のフィールドは簡単です。単語を表す \w+ を使ってやればいいだけです。また、カンマは単語を構成する文字ではないので、\w にはマッチしません。

次のフィールドも単純に数字のマッチです。ただ、数字が何文字来るか分からないので、\d+ と書きます。

最後のフィールドも、メタ文字の \d+ と リテラルの yen がくっついているだけです。


メタ文字とリテラルの組合せで、どんな文字列でも表現できることが分かったでしょうか。しかし、今のままでは ReadOnly です。
次は、マッチした文字列に対して、置換などの処理をすることについて説明します。


6.2 置換演算子

2.1 節の例で「SIZE="+1" になっているのを SIZE="+3" にする」という置換の作業を正規表現を使って行いました。文字列処理において、置換作業は重要なウェイトを占めてきます。


○ 置換演算子 s///
置換を行うために Perl には演算子が用意されています。この演算子の使い方は簡単で、
$target =~ s/置換する文字列の正規表現/置換語の文字列/;
という形になります。
$target という変数に "my name is shimizu" という文字列が入っているとき、shimizu を ryo に置換するには、
$target =~ s/shimizu/ryo/;
と記述するだけです。このように置換したい文字列がリテラルで書けるような場合は非常に楽ですが、それが正規表現を使わないと表現できないような文字列になったときに、その文字列パターンを表現できる正規表現をきっちりと書いてやらなければいけません。


○ 特殊変数 $N
特殊変数 $N(N=1,2,3...) は正規表現にマッチした部分の文字列が格納してある変数です。

$target = "my name is shimizu";
if($target =~ /my name is (\w+)/)
{
  print $1;
}

このプログラムの結果は shimizu が出力されます。2行目の if 文の中の正規表現の中身を詳しく解説すると、 \w+ は単語にマッチするメタ表現です。そしてその前に my name is というリテラルがあります。ここで大切なのは \w+ を (\w+) と書くことです。メタ文字の部分を () でくくる事によって、Perl はそこのメタ文字でマッチした文字列(この場合は shimizu) を特殊変数 $1 に格納してくれます。
このように、my name is の後にくる単語を変数に格納できることによって、その変数の値によって条件分岐をおこなうことができます。

if($target =~ /my main editor is (\w+)/)
{
  print "bad!\n" if $1 =~ /emacs/i;
  print "good!\n" if $1 =~ /vi/i;
}

これは my main editor の次にくる単語が emacs(i オプションにより大文字小文字区別なし) だったら bad! と表示し、vi であれば good! と表示します。

特殊変数 $N の N の部分は、正規表現中での () にくくられた部分の数になります。

$target = "my name is shimizu";
$target =~ /my (\w+) is (\w+)/)

とすれば、$1 に "name" 、$2 に "shimizu" が格納されます。

この特殊変数を使うことで、2.1 節のプログラムに変化を加えることができます。

SIZE=N になっているところを SIZE=N+1 に変える
open FILE , 'yomitai.html';
@_ = <FILE>;
close FILE;
foreach $temp (@_)
{
  if($temp =~ /SIZE="(\+\d+)"/)
  {
    $before_size = $after_size = $1;
    $after_size++;
    $temp =~ s/SIZE="\+$before_size"/SIZE="+$after_size"/g;
  }
}
open FILE , '>dekaimojino.html';
print FILE @_;
close FILE;
プログラム6.3

このプログラムにより、SIZE="+1" となっているところを SIZE="+2" に、SIZE="+2" となっているところを SIZE="+3" に変えることが出来ます。
置換演算子の使い方は以上の通りです。置換演算子がどうこう、ではなく正規表現をいかに書けるか、ということが大切であることが理解できたと思います。


7. 特殊変数 $_ 、特殊配列 @_

Perl はスクリプト言語という性質上、コードをより短く書けるような裏技が存在します。ルールは単純ですが、やっつけ仕事をするときには非常に重宝します。

$_ は宣言しなくても使えるグローバル変数です。ただ使えるというわけではなく、大抵の標準関数のデフォルトの引数に指定されています。通常、関数は引数をとりますが、Perl においては(変数を引数にとる関数で)引数を省略すると、$_ が引数に与えられたものとして動作します。
たとえば、
$_ = "test";
print;

とすれば、test という文字列が出力されます。また、関数だけでなく、正規表現のための =~ 演算子も $_ をデフォルトの引数対象として動作します。
$_ = "this is test";
if(/test/)
{
  print "test is included\n";
}

とすれば /test/ で書いた正規表現のマッチ対象が $_ として if 文が評価されます。
さらに foreach 文で、配列の中身を展開する先も $_ がデフォルトになっています。
@test = (1 , 2 , 3);
foreach (@test)
{
  print;
}

のような使い方もできます。これによってタイピング量を減らすことが出来ます。

@_ も $_ 同様、配列を引数にとる関数のデフォルトの引数として認識されます。一番よく使われるのが shift 関数です。shift 引数に与えられた配列の一番最初の要素を取り出し、配列の中身をシフトします。つまり今まで $_[1] だったものが $_[0] になります。@test という配列の一番最初の要素を取り出して、変数 $arg その値を格納するには、
$arg = shift(@test);
と書きます。
@_ は shift 関数のデフォルトの引数となっているので、
$arg = shift;
と書けば、@_ の最初の要素を $arg に格納することが出来ます。
shift 関数が最もよく使われるのは、サブルーチンでの引数の格納です。5.2 節で説明したように、Perl ではサブルーチンへの値の引渡しに @_ を使います。サブルーチン側で、引数を格納するための変数を用意し、@_ の中身をそこに格納するには以下のように行うことができます。

sub test
{
  my $first = shift;
  my $second = shift;
  my $third = shift;
  ...
}


これらの例のように引数のデフォルトが $_ 、 @_ になっているものはたくさんあります。デフォルト引数を使うと、無駄なタイピングを減らすことができるので、より早くコードが書けるようになります。ただ、@_ はサブルーチンの値の受渡しに使われるので、むやみに使うと思いがけない動作をする可能性があるので注意してください。


8. Reference

今まで説明しなかったものを含めて、関数、演算子、特殊変数などの使い方を説明します。


9. 正規表現サンプル集


10. Perl スクリプトサンプル集

今まで説明に使って来たサンプル集は、多少非現実的な内容だったので、ここでは現実的なプログラムをサンプルとして紹介します。
Perl スクリプトの使い方は、hoge.pl というファイルに Perl の文を書き込み、
perl hoge.pl
として実行するか、hoge.pl の1行目に
#!/usr/bin/perl
と書いておいて、
./hoge.pl
として実行するかの二通りのやり方があります。どちらのやり方にも対応できるように、ここではスクリプトの1行目に必ず #!/usr/bin/perl を記述することにします。