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

Perl マッチ演算子[m]/置換演算子[s]/変換演算子[y][tr]

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

Perl マッチ演算子[m]/置換演算子[s]/変換演算子[y][tr]

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

正規表現 / Regular Expression

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

演算子 / Operators

修飾子 / Modifiers

量指定子 / Quantifiers

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

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

文字クラス / Character Classes

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

...etc.

Perl マッチ演算子[m]/置換演算子[s]/変換演算子[y][tr]

 Perlの正規表現、パターンマッチ演算子としては次のような演算子があります。

パターンマッチ演算子
演算子用途
m  m 演算子・マッチ演算子・パターン検索
  match の m 
 パターンをスラッシュ(既定)で括る
 /pattern/
 パターンセパレータが既定の場合のみ m を省略可
 m ! pattern !
s  s 演算子・置換演算子・パターン置換
  sed の s 演算子の s で元は substitution の s 
 既定のパターンセパレータはスラッシュ
 s/before/after/
 (基本的にパターンにない全ての文字で代替可)
 s#before#after#

 正規表現ではありませんが、パターンマッチ演算子と併用されることも多い変換演算子としては次のような演算子があります。

変換演算子
tr 一文字変換
 transliterationのtr
 tr/a/b/
 tr a , b
 UNIXsedユーザーの為に便宜的に仕様化、推奨はPerl固有y演算子
y trと同等のPerlオリジナルの演算子
 y/a/b/
 y ! a ! b !

 更にこれらに関係の深い演算子として次のような演算子もあります。

=~ イコールとチルダ・イコールチルダ演算子
 左辺の文字列に右辺のパターンによる部分文字列が含まれるかを評価
右辺が置換演算子・変換演算子による置換・変換で且つパターンにマッチする場合、実行し左辺に反映
!~ 感嘆符とチルダ・エクスクラメーションチルダ演算子
 左辺の文字列に右辺のパターンによる部分文字列以外が含まれるかを評価
 =~イコールチルダ演算子の否定
m//演算子と=~演算子

 m//演算子は、特定の区切り文字に挟まれた式にマッチするものを探す為に利用し、デフォルトの区切り文字(セパレータ)であるスラッシュを利用する場合にはmを省略することができ、mを伴い他とバッティングしなければあらゆる文字をセパレータとすることができます。

 $foo=~m/^[a-z]/; 

 $foo=~/^[a-z]/; 

 $foo=~m ! ^[a-z] !; 

 また、=~(イコール+チルダ)演算子は、右辺の式で左辺を評価することができます。

 よって先の例は何れも$fooにおいて先頭が小文字のaからzで始まっているかを評価している式ということで、例えば、

 if ( $foo=~m ! ^[a-z] ! ) { } 

のように利用します。

変換演算子[tr][y]と置換演算子[s]

 「m//」はマッチするものの検索・抽出ですが、その他に変換演算子tr、置換演算子sed由来のs演算子というものもあり、

 tr/変換前パターン/変換後パターン/; 

 s/置換前パターン/置換後パターン/; 

 つまり、

 $foo=~tr/a/b/; 

 $bar=~s/[a-z][0-9]$//; 

のように記述できます(記述スタイルはカッコ付きやスペースやカンマで区切るなど他にもあります)。

 因みに前述の文字クラスで利用した「^」は、「~以外にマッチ」する事を意味し、下記は「小文字アルファベットで始まらない123」という条件となり、

 $hoge=~s/[^a-z]123//; 

 一方、前述の「主なメタ文字一例」の通り、式の先頭に^を記述すると「先頭」「~で始まる」を意味するので

 $hoge=~s/^[a-z]123//; 

とあれば、「先頭がアルファベット小文字で始まる123」を表します。

 例えば「$xyz=~s/^a/b/」のように記述するとスカラー変数「$xyz」の展開後の中身の「先頭」が「a」とマッチするものを「b」に置き換えるという意味になります。

 先頭を表すのは「^」ですが、他方、最後尾(末尾)を表すには「$」を利用し、

 $xyz=~s/a$/b/; 

のように記述するとスカラー変数「$xyz」の展開後の中身の末尾が「a」とマッチするものを「b」に置き換えるという意味になります。

 尚、

 $ret = $xyz=~s/a$/b/; 

とした時、$retには「真理値/真偽値」が入りますが、

 ( $ret = $xyz ) =~s/a$/b/; 

とすると$retには「置換後の値」が入ります。

パターン参照

$ cat test3.pl

#!/usr/bin/perl

 $string = "Perl is good" 

 $string=~s/(.+)\s(.+)\s(.+)/$3/; 

 print "$string\n"; 

$ ./test3.pl

good

 また、s/置換前/置換後/においても置換「後」に置換「前」のパターンを参照する為に前述した$1,$2...$9を利用できます。

 s/置換前/置換後/で置換後パターンにおいて置換前パターンを参照する際には、$1,$2...$9の他、\1,\2...\9を利用できます。

 UNIX/Linuxのsedコマンドの場合は、\1,\2...\9を利用する場合、置換前パターンの正規表現用グループ化の丸かっこ( )には\(\)のようにエスケープする必要がありますが、Perlではその必要はなく$1も\1同様に利用できます。

パターンマッチ変数意味
$`パターンの前にマッチ
$&当該パターンにマッチ
$'パターンの後にマッチ

 他にパターンマッチに利用できるPerl固有の特殊な変数として$`、$&、$'があり、それぞれパターンの前、当該パターン、パターンの後にマッチします。

$ cat test3.pl

#!/usr/bin/perl

 $string = "Perl is good script" 

 $string=~s/good/$&/; 

 print "$`$'\n"; 

$ ./test3.pl

Perl is  script

 sedにもマッチしたパターン&があり、$&はsed由来だと思われますが、$`、$'はPerl固有です。

 この例では[good]が$&にマッチ、[Perl is ]が$`にマッチ、[ script]が$'にマッチするので出力結果は[good]を除外し、isの後にスペースが2つある[Perl is  script]となります。

$ cat test4.pl

#!/usr/bin/perl

 $string = "123xxx123xxx" 

 $string=~s/([1-3]+)([a-z]+)\g1\g2/\1\2/; 

 # 逆参照で同じ結果を得る為には

 # $string=~s/([1-3]+)([a-z]+)\g{-2}\g{-1}/\1\2/; 

 print "$string\n"; 

$ ./test4.pl

123xxx

 更にPerlでは置換「前」の式内で置換「前」のパターンを左から順次参照することができる\g1,\g2...\g9や逆参照である...\g{-2}、\g{-1}があります。

 前者の数値と後者の数値は正負によって参照する順番が逆になり、\g1,\g2...\g9では、\g1が置換前の最初のパターンを、...\g{-2}、\g{-1}では、\g{-1}が置換前パターンの直前のパターンを参照します。

 つまり、前者は置換後パターンの$1..$9、\1..\9による参照と参照する順番は同様です。

ホーム前へ次へ