気の向くままに辿るIT/ICT/IoT
Perl

Perl 量指定子

ホーム前へ次へ
Perlのパターンマッチで量指定子ってどうやって使うの?

Perl 量指定子

Perl 正規表現/パターンマッチ・パターンマッチング

正規表現 / Regular Expression

パターンマッチング / Pattern Match / Pattern Matching

演算子 / Operators

修飾子 / Modifiers

量指定子 / Quantifiers

メタ文字/メタキャラクタ / Metacharacters

エスケープシーケンス / Escape sequences

文字クラス / Character Classes

特殊なエスケープ文字 / Special Escapes

...etc.

Perl 量指定子

 Perlでは量指定子でパターンの出現回数を指定することができますが、これらはPerlに限らず、UNIX/Linux環境及び各種UNIX/Linuxコマンドでも一般に利用されるものです。

量指定子意味
* 0 回以上にマッチ
+ 1 回以上にマッチ
? 0 回か 1 回マッチ
{n} n 回マッチ
{n,} n 回以上マッチ
{n,m} n 回以上 m 回以下にマッチ

 Perlの生みの親ラリー・ウォール氏は、当初、Pearlという名称にしたかったものの既に言語の名称として使われていた為、最終的に似たようなフレーズとしてPerlという名称に落ち着いたとされています。

パターンperlpearl
p[ae]*rlマッチ
p[ae]+rl
p[ae]{0,}rl
p[ae]{1,}rl
p[ae]{0,1}rl
p[ae]{0,2}rl
p[ae]{1,2}rl
p[ae]{2}rl-マッチ
p[ae]{2,}rl
...etc.

 Pearlは真珠を表す米英語ということで、これを量指定子を使ったパターンマッチのサンプルとして使ってみるとこのよう結果になります。

 何れもメタ文字のブラケットを使って a または e という文字クラスを作り、 p に続いて a または e が量指定子で示す分だけ続き、 rl で終わる文字列というパターンを表しています。

[prompt] cat foo.pl

#!/usr/bin/perl

$a="pearl";

if ($a=~/p[ae]{2}rl/) { print "\$a1 is $a\n"; }

$a=~s/(p[ae]{2,}rl)/perl/;

unless ($a=~/p[ae]{2}rl/) { print "\$a2 is $a\n"; }

[prompt] perl foo.pl

$a1 is pearl 

$a2 is perl 

 これをイコールチルダ演算子[=~]やパターンマッチ演算子であるm演算子と併用すれば条件分岐やループ条件として利用することもできますし、置換演算子であるs演算子と組み合わせることも可能です。

 また、量指定子のメタ文字の丸カッコを使ったグループ化と特殊な$1...$9といった位置変数や\g1..\g9といったエスケープシーケンスによる後方参照も一般的に利用されます。

最短マッチと最長マッチ

[prompt] cat bar.pl

#!/usr/bin/perl

$a="PerlPearlPaul";

$b="PerlPearlPaul";

$a=~s/P(.+)l.*/$1/;

print "\$a is $a\n";

$b=~s/P(.+?)l.*/$1/;

print "\$b is $b\n";

[prompt] perl bar.pl

$a is erlPearlPau

$b is er

[prompt]

 あるパターンにマッチさせようと考えた時、パターンの末尾にあたる位置が複数該当してしまう場合、Perlは最も後ろにある位置をパターンの末尾として認識しますが、これを最長マッチと呼び、Perlでは、この最長マッチが既定となっています。

 この時、最短の位置にマッチ(最短マッチ)させたい場合には、量指定子の疑問符 ? を利用します。

 サンプルでは、"PerlPearlPaul"という、とても紛らわしい文字列に対し、大文字の P で始まり、数文字続けて小文字の l (エル)で終わるパターンを置換演算子s演算子で P と l に挟まれた部分に置換する例です。

 挟まれる部分は丸カッコでグループ化し、グループ化した位置を保持する特殊な変数$1で参照することで置換しています。

 変数$aの式では疑問符 ? をつけていないのでPerl既定の最長マッチで最初の P (PerlのP)と最後の l (Paulの l )に挟まれた部分"erlPearlPau"が、また、変数$bの方は疑問符 ? をつけたので最短マッチでPerlの P と、やはり、Perlの l に挟まれた部分"er"が、結果として出力されます。

ホーム前へ次へ