Perlはココがポイント!正規表現や配列などの疑問を解説

公開日:2021.03.31

スキルアップ
 

Perlは、インタプリタタイプのプログラミング言語です。Web開発の主流ではありませんが、文字列操作が手軽にできることなどから、開発現場ではツールなどに使われることも多く、役立つシーンはまだまだあります。本記事では、Perlを実際に使う上で注意すべき「正規表現」や「配列」などについてまとめました。

Perlとは

Perlとは、インタプリタ言語でコンパイルせずにそのまま実行できるプログラミング言語です。Web上でCGI(Common Gateway Interface)を実現するために開発され、基本文法や記法はC言語(詳しくはこちらの記事でも解説)と似ています。しかし、さらに自由度が高くてシンプルな書き方ができる点が大きな特徴です。

Perlをすぐに使いたい場合は、チュートリアルの記事を用意していますのでご活用ください。

ここからは、Perlのプログラミングで初心者がつまずきやすいポイントとして、制御構造や文字列操作・配列・正規表現についてまとめました。悩んでいるキーワードがあれば、リファレンス的に確認してください。

Perlと制御構造の整理

Perlの制御構造は、他のプログラミング言語と同じく「真と偽」「条件式」「ループ文」「ループ制御」「三項演算子」があります。このうち、さまざまなパターンがあって混乱しやすい「条件式」と「ループ」について取り上げました。

条件式:ifとunless

ifとunlessは、どちらも指定された条件を確認、後続の処理を実行するかどうかを決める条件式です。

if 条件が真なら処理を実行
unless 条件が偽なら処理を実行

例えば、以下のようなプログラムを組んだとしましょう。

if ( 条件A ) { 処理A }
elsif ( 条件B ) { 処理B }
else { 処理C }

日本語で説明すると以下の通りの動きになります。

  • 条件Aが真なら処理Aの処理を実行
  • 条件Aは偽だが条件Bが真なら処理Bを実行
  • 条件A・条件Bともに偽なら処理Cを実行

ちなみに、C言語やJavaなら「else if」ですが、Perlは「elsif」と表現するのでご注意ください。

一方、unlessの場合は、どうなるでしょうか。

unless ( 条件A ) { 処理A }
elsif ( 条件B ) { 処理B }
else { 処理C }

  • 条件Aが偽なら処理Aの処理を実行
  • 条件Aは真だが条件Bが偽なら処理Bを実行
  • 条件A・条件Bともに真なら処理Cを実行

ループ:while・do・for・foreachの使い分け

Perlのループ文は、以下の6種類あり、それぞれに少しずつ処理内容が異なります。

while 条件が真の間処理を実行
until 条件が偽の間処理を実行
do while 処理を1回実行した後、条件が真の間処理を実行
do until 処理を1回実行した後、条件が偽の間処理を実行
for
  • 1.
    カウンターの初期化条件を最初に1回実行
  • 2.
    その後カウンターの条件式が真であれば処理実行
  • 3.
    次にカウンターの増減式を実行して2の処理に戻る
foreach 渡したリスト値の先頭の値を制御変数にセットして処理実行をリスト値の最後まで繰り返す

処理を作成していて後から理解しやすいのは、whileとforです。基本的には、この2種類を利用し、別のループ文のほうが簡潔に処理を表現できる場合のみ、他の4種類を検討してみてください。

Perlと文字列操作の基礎

Perlは、文字列操作が使いやすくて便利です。基本の文字列操作関数についていくつか紹介します。

文字列の検索:indexとrindex

indexとrindex文字列検索の基本的な関数です。指定した文字列から検索文字列が最初に出現する場所を知りたい場合はindex、検索文字列が最後に出現する場所を知りたい場合はrindexを使いましょう。

index 文字列と開始位置、検索文字列を指定して、検索文字列が最初に出現する位置を返す関数です。開始位置を省略すると、先頭(0)から検索します。検索文字列が見つからない場合は-1 を返します。
rindex 指定する情報は同じで、検索文字列が「最後」に出現する位置を返す点がindexと違う動きをする関数です。その他の挙動はindexと同じです。

文字列の操作:substrとsplit

文字列操作関連の関数は、文字列の加工で何かとお世話になる使用頻度の高い関数です。substrは、文字列の取り出し・置き換え・削除・追加に使えます。substr関数を式の右側に置くと文字列の取り出しができ、四季の左側に置くと文字列の置き換え・削除・追加が可能です。

splitとjoinは、文字列と配列の操作を簡単に行える関数です。区切文字の入った文字列を配列に変換し、joinは配列を区切文字の入った1つの文字列に変換します。

substr 対象文字列と開始位置、文字列長を指定して指定の長さの文字列を返す関数です。開始位置は0から数えます。文字列長を省略すると開始位置以降~文字列末尾の文字列を返します。
split 対象文字列と区切文字を指定すると、配列に分解して返す関数です。
join splitと逆の動きをする関数です。配列と区切文字を渡すと、配列の先頭要素から順番に最後の要素までを区切文字で区切った1つの文字列に合成して返します。

splitとjoinは、特にCSVファイルを扱うのに便利です。

文字列の整形:printfとsprintf

printfとsprintfは、どちらも文字列を指定のフォーマットに従って整形します。両者の違いは、「ファイルハンドルに出力するか」「値を返すか」です。

printf 指定のフォーマットに従い文字列を成形し、ファイルハンドルに出力
sprintf 指定のフォーマットに従い文字列を成形した値を返す

フォーマットの書式については、とりあえず「%c:1文字」「%s:文字列」「%d:10進整数」を覚えておきましょう。

Perlとリスト・配列

リストと配列は、どちらも複数の値をまとめて管理するために用います。リストと配列の概要と両者の違いは、少し難しいかもしれないため、ここで整理しましょう。

リストと配列の解説

リストは、順番に並べられた複数の「値」で、「(値1, 値2, 値2)」のように表現します。具体的には、数字のリストなら「(1, 2, 3)」、文字列なら「(“山”, “川”, “谷間”)」と記述します。

配列は、リストと似ていますが、値ではなく複数の「変数」をまとめて管理する点がリストとの相違点です。配列は、「@+配列名」と変数宣言して使用します。配列名は、英字から始まり、英字・数字・アンダーバーを組み合わせて作成。配列の宣言では、要素の個数を指定する必要はありません。

配列演算子と配列関数

配列には、数値や文字列、変数を代入することができます。以下は、代入の例です。

  • 数値の代入例:@aaa = (1, 2, 3);
  • 文字列の代入例:@bbb = (“apple”, “banana”, “berry”);
  • 変数の代入例:@ccc = ($hoge1, $hoge2, $hoge3);

配列の中の要素は、「$配列名[添え字]」という書き方で、各要素にアクセス可能です。先頭は0から始まります。

@bbb = (“apple”, “banana”, “berry”);

という配列への代入は、以下の書き方も同じ意味です。

$bbb[0] = "apple";
$bbb[1] = "banana";
$bbb[2] = "berry";

また、配列は直接操作もできますが、並べ替えや追加・削除など配列の操作は、以下のような配列関数を使えば便利です。

  • sort:配列の順序をソートする
  • reverse:配列の順序を逆順にする
  • push:配列の末尾へ要素を追加
  • pop:配列の末尾の要素を削除
  • unshift:配列の先頭へ要素を追加
  • shift:配列の先頭の要素を削除

覚えると便利なクォート構文

配列に値を代入する便利な書き方がクォート構文です。クォート構文は、カッコで括られた文字列より、空白以外の部分からリストを作成します。

  • 配列に値を代入:@color = ('Red', 'Green', 'Blue', 'Orange');
  • クォート構文での書き方:@color = qw(Red Green Blue Orange);

Perlと正規表現

Perlの正規表現は、詳細な表現ができると言われています。まず、正規表現そのものについて整理してから、具体的な記載方法について見ていきましょう。

そもそも正規表現とは

正規表現とは、文字列をパターン化して表現する方法のことです。正規表現が活躍する場面は文字列の検索で、例えば「aaa」から始まる任意の文字列を検索する際、Windowsでは「aaa*」という正規表現で検索します。

パターンマッチ演算子

Perlのパターンマッチ演算子は「=~」です。スラッシュで囲んだパターンを含む文字列がある場合に真を返します。パターンに一致する文字列を探す場合は、「文字列 =~/パターン/」と記載します。パターンに一致しないかどうかチェックする場合は「!~」を使用します。

パターンマッチの書き方は省略形もあり「/パターン/」と記載するだけでも直前の変数「$_」の中にパターンが含まれているかどうかを検索可能です。また、パターンマッチ演算子「/」は、以下の記載方法で、別の記号(空白以外)に置き換えることもできます。

・m[任意の区切文字]パターン[任意の区切文字]

例えば「|」を区切り文字にしたい場合は、以下のように記載します。

・m|パターン|

URLのようにスラッシュを多く含む文字列を扱う場合は、スラッシュが続くと分かりにくいため、この機能も活用すると良いでしょう。

メタ文字とエスケープ

正規表現を行ううえで、次のようなメタ文字と呼ばれる特殊な意味を持つ文字があります。パターンを囲む「/」や量指定子の「*」「?」などはメタ文字です。これらのメタ文字を単なる文字として扱いたい場合はエスケープに「\」を直前に付加し、「\*」「\?」「\\」などと表現します。

置換演算子と変換演算子

置換演算子とは、パターンマッチした部分を指定の文字列に置き換える表現です。

・「=~s/パターン/置換文字列/」:指定したパターンに一致したら置換文字列に置き換える

変換演算子は、指定した返還対象の文字を変換後の文字に変換する表現です。

・「=~tr/変換対象の文字/変換後の文字/」

例えば、「tr/a-z/A-Z/」と記載すると、英小文字の部分が英大文字に変換されます。

正規表現を利用する関数splitとjoin

文字列操作のsplit関数は正規表現を利用して文字列を分解して配列にし、join関数は、逆に配列から特定の区切文字で区切った1つの文字列を生成します。

$mojimoji = "aaa:bbb:ccc";
@mojimoji = split(/:/, $mojimoji);(「;」で区切って配列に変換)
$mojimoji = join(":", @mojimoji); (配列の要素を「;」でつないで1つの文字列に変換)

Perlでつまずいたらもう一度リファレンスを確認!

Perlは、他のプログラミング言語と似ているところもありますが、違う部分もあり、プログラムを書いていると迷う部分も出てきます。本記事で紹介した配列や正規表現など、コンパイル不要で動かしながら確認しましょう。

Web開発案件では、Perlの知識が役立つ場面もたくさんあります。AKKODiSでは、Webエンジニアの求人も多数ありますので、気になる案件があればぜひ応募をご検討ください。

(2021年3月現在)

AKKODiSコンサルティングに関するお問い合わせ