コーディング · プログラミング言語
Perl入門:初心者向けチュートリアル
結論
Perlは、1987年にLarry Wallが作った動的なスクリプト言語で、テキスト処理と強力な組み込みの正規表現で知られています。ほとんどのUnix系システムに標準で入っており、システム管理、ログ処理、バイオインフォマティクスなどで使われています。このページでは、Perlの実行、スカラー、配列とハッシュ、制御構文、サブルーチン、リファレンス、正規表現、dieとevalによるエラー処理を扱います。
正規表現テストを開くPerlとは何か、何に使うのか
Perlは、1987年にLarry Wallが作った高水準の動的型付け言語です。テキスト処理とレポート生成のために設計され、Unixのシステム管理や初期のWeb開発をつなぐ「糊(のり)」の言語として広まりました。Perlの正規表現は大きな影響を与え、ほかの多くの言語が「Perl互換」の正規表現構文を採用しています。
現在のPerlは、システム管理スクリプト、ログやテキストの処理、バイオインフォマティクス、レガシーなWebアプリケーション、ワンライナーのコマンドラインフィルターなどに使われています。ほとんどのLinuxやUnixシステムに標準で入っています。CPAN(Comprehensive Perl Archive Network)には、再利用できる膨大な数のモジュールが公開されています。このチュートリアルはPerl 5を扱います。かつてPerl 6と呼ばれていた言語は、現在はRakuという別の言語です。
Hello, worldの実行
perl -vでPerlがインストールされているか確認します。Windowsでは、Strawberry Perlがよく使われるディストリビューションです。スクリプトの冒頭には必ずuse strict;とuse warnings;を書きましょう。タイプミスや安全でないコードを見つけてくれます。
#!/usr/bin/env perl
use strict;
use warnings;
print "Hello, world!\n";perl hello.pl
# Hello, world!
perl -e 'print "Hello from a one-liner\n"'文末にはセミコロンを付けます。コメントは#で始まります。二重引用符の文字列では変数と\nなどのエスケープが展開され、単一引用符の文字列はそのままの文字列になります。
変数:スカラー・配列・ハッシュ
Perlの変数は、値の種類を示す記号(シギル)で始まります。変数はmyで宣言し、外側のブロック内だけで使えるローカル変数にします。
use strict;
use warnings;
my $name = "Perl"; # scalar: one value
my $year = 1987;
my @langs = ("Perl", "C", "sh"); # array: ordered list
my %port = (http => 80, https => 443); # hash: key-value pairs
print "$name since $year\n"; # Perl since 1987
print "First: $langs[0]\n"; # First: Perl (element is a scalar, so $)
print "Count: ", scalar(@langs), "\n"; # Count: 3
print "HTTPS: $port{https}\n"; # HTTPS: 443
print "Sum: ", "10" + 5, "\n"; # Sum: 15 (strings convert to numbers)
print "Join: " . "a" . "b" x 3, "\n"; # Join: abbb| シギル | 種類 | 例 |
|---|---|---|
$ | スカラー:数値、文字列、またはリファレンス | my $n = 42; |
@ | 配列:スカラーの順序付きリスト | my @list = (1, 2); |
% | ハッシュ:順序のないキーと値のペア | my %h = (a => 1); |
& | サブルーチン(あまり書きません) | &name |
制御構文
Perlにはif、elsif、else、unless、while、until、for、foreachがあります。短い文の後ろに条件を付けて、英語のように読める書き方もできます。nextは次の繰り返しへ進み、lastはループを抜けます。
use strict;
use warnings;
my $score = 72;
if ($score >= 90) {
print "A\n";
} elsif ($score >= 70) {
print "B\n"; # B
} else {
print "C\n";
}
print "passed\n" if $score >= 50; # statement modifier
print "not perfect\n" unless $score == 100;
for my $i (1 .. 3) {
print "i = $i\n";
}
my @names = ("ann", "bo");
foreach my $n (@names) {
next if $n eq "bo"; # skip to the next item
print ucfirst($n), "\n"; # Ann
}
my $k = 3;
while ($k > 0) { $k--; }偽になる値は、0、"0"、空文字列""、空のリスト、undefです。それ以外はすべて真です。
サブルーチン
関数はsubで定義します。引数は特別な配列@_で渡され、最初の行でそれを名前付きの変数にコピーするのが定番です。サブルーチンはスカラーもリストも返せます。
use strict;
use warnings;
sub add {
my ($x, $y) = @_; # arguments arrive in @_
return $x + $y;
}
sub greet {
my ($name, $greeting) = @_;
$greeting //= "Hello"; # default if undefined
return "$greeting, $name!";
}
sub stats {
my @nums = @_;
my $sum = 0;
$sum += $_ for @nums;
return ($sum, $sum / @nums); # return a list
}
print add(2, 3), "\n"; # 5
print greet("Ann"), "\n"; # Hello, Ann!
my ($total, $avg) = stats(4, 8, 6);
print "$total $avg\n"; # 18 6現代のPerlはシグネチャにも対応していて、sub add($x, $y) { ... }のように書けます。use v5.36;以降を指定すると有効になり、strictとwarningsも同時に有効になります。
配列・ハッシュ・リファレンス
配列とハッシュには、push、pop、shift、sort、map、grep、keys、existsといった強力な組み込み関数があります。入れ子のデータにはリファレンスを使います。[ ... ]は配列リファレンス、{ ... }はハッシュリファレンスを作り、->でそれをたどります。
use strict;
use warnings;
my @nums = (5, 3, 8, 1);
push @nums, 9; # add to the end
my $last = pop @nums; # remove from the end: 9
my @sorted = sort { $a <=> $b } @nums; # numeric sort
my @doubled = map { $_ * 2 } @sorted;
my @big = grep { $_ > 4 } @sorted;
print "@sorted | @doubled | @big\n"; # 1 3 5 8 | 2 6 10 16 | 5 8
my %age = (ann => 31, bo => 25);
$age{cy} = 40;
delete $age{bo};
for my $who (sort keys %age) {
print "$who is $age{$who}\n"; # ann is 31 / cy is 40
}
print "has ann\n" if exists $age{ann};
# references build nested data structures
my $user = { name => "Ann", langs => ["Perl", "SQL"] };
print "$user->{name} knows $user->{langs}[1]\n"; # Ann knows SQL
print scalar @{ $user->{langs} }, "\n"; # 2sortブロックの中では、$aと$bが比較される2つの要素です。<=>は数値として、cmpは文字列として比較します。単純なsort @listは文字列として並べ替えるため、10が9より前に来ます。
正規表現
正規表現はPerlの構文に組み込まれていて、これが最大の特徴です。=~でマッチm/.../や置換s/.../.../を適用します。キャプチャしたグループは$1、$2などで参照でき、g(グローバル)やi(大文字・小文字を区別しない)といった修飾子は閉じのスラッシュの後ろに付けます。
use strict;
use warnings;
my $line = "2026-10-31 ERROR disk full on /dev/sda1";
if ($line =~ /^(\d{4})-(\d\d)-(\d\d)\s+(\w+)/) {
print "year=$1 level=$4\n"; # year=2026 level=ERROR
}
(my $masked = $line) =~ s/\d/#/g; # copy, then replace digits
print "$masked\n"; # ####-##-## ERROR disk full on /dev/sda#
my @words = split /\s+/, $line;
print scalar(@words), " words\n"; # 6 words
my %h = ("a=1, b=2, c=3" =~ /(\w)=(\d)/g); # pairs into a hash
print join(",", map { "$_$h{$_}" } sort keys %h), "\n"; # a1,b2,c3qr/.../を使うと、コンパイル済みのパターンを変数に保存できます。x修飾子を使うと、長いパターンをコメント付きで複数行に分けて書けます。
エラー処理
dieは例外を発生させ、warnは警告を標準エラー出力に表示します。eval { ... }は例外を捕捉し、エラーメッセージを$@に入れます。openなどのシステムコールは失敗すると偽を返し、$!にOSのエラーを設定するので、or dieで確認します。
use strict;
use warnings;
sub divide {
my ($x, $y) = @_;
die "division by zero\n" if $y == 0;
return $x / $y;
}
my $result = eval { divide(1, 0) };
if ($@) {
print "Caught: $@"; # Caught: division by zero
}
open(my $fh, "<", "missing.txt")
or print "Cannot open: $!\n"; # Cannot open: No such file or directory\nで終わるdieのメッセージは、書いたとおりに表示されます。改行がなければ、Perlはファイル名と行番号を付け足します。Perl 5.34以降は実験的なtry/catch機能もあり、Try::Tinyなどのモジュールも広く使われています。
小さな完成プログラム:ログレベルのカウント
このスクリプトは、コマンドラインで指定したファイルまたは標準入力からログを読み、レベルごとに行数を数えて、並べ替えた集計を表示します。ダイヤモンド演算子<>、正規表現、ハッシュ、printfの使い方がわかります。
#!/usr/bin/env perl
# logstat.pl: count log levels in a file or standard input
use strict;
use warnings;
my %count;
my $lines = 0;
while (my $line = <>) { # reads files named on the command line, or STDIN
chomp $line;
$lines++;
next unless $line =~ /\b(INFO|WARN|ERROR)\b/;
$count{$1}++;
}
printf "%d lines read\n", $lines;
for my $level (sort { $count{$b} <=> $count{$a} || $a cmp $b } keys %count) {
printf "%-5s %3d\n", $level, $count{$level};
}perl logstat.pl app.log
# 120 lines read
# INFO 97
# WARN 18
# ERROR 5次に学ぶこと
- perldoc.perl.orgのperlintroなどのチュートリアル。
perldoc perlintroでオフラインでも読めます。 - 『Learning Perl』と『Modern Perl』。初心者向けの有名な2冊です。
- MetaCPAN。CPANモジュールの検索インターフェースです。
- 正規表現の完全なリファレンスであるperlreとperlretut。
よくある質問
Perlは今でも使われていますか?
はい。ほとんどのUnix系システムに標準で入っており、システム管理、テキスト処理、バイオインフォマティクス、長く稼働している業務システムでは今も一般的です。ただし、新規のWebプロジェクトでPerlを選ぶ例は減っています。
PerlとRakuの違いは何ですか?
RakuはPerl 6として始まりましたが、設計の異なる別の言語になりました。Perl 5は独立して開発が続けられており、Perlという名前はこのPerl 5を指します。
Perlの変数がなぜ$、@、%で始まるのですか?
シギルは、得られる値の種類を表します。単一のスカラーなら$、リストなら@、ハッシュなら%です。このため、@itemsの1つの要素は$items[0]と書きます。
Perlのchompは何をしますか?
chompは文字列の末尾の改行を取り除きます。ファイルやキーボードから1行読み込んだ後に、ほとんどの場合必要になります。
Perlは正規表現が得意ですか?
はい。正規表現はPerlの中核の構文の一部です。ほかの多くのツールや言語が使う正規表現ライブラリPCREの名前も、Perlの正規表現のスタイルに由来しています。