クォートはリテラル値であると考えるのが普通ですが、Perl において、クォー トは演算子として働き、さまざまな展開やパターンマッチの機能を持っています。 そのような動作をさせるのに、Perl は慣習的にクォート文字を使っていますが、 どの種類のクォートも、自分でクォート文字を選べるようになっています。以下 の表では、{} がその選んだ区切文字のペアを示しています。選んだ区切文字が 括弧の類でない場合には、前後の文字として同一のものを使いますが、4 つの括 弧 ((), <>, [], {}) の場合にはネストできます。
通常記法 汎用記法 意味 展開
==========================================
'' q{} リテラル 不可
"" qq{} リテラル 可
`` qx{} コマンド 可
qw{} 単語リスト 不可
// m{} パターンマッチ 可
s{}{} 置換 可
tr{}{} 変換 不可
展開が行なわれる構文では、"$" や "@" で始まる変数が、以下のシーケンスと 同時に展開されます:
\t タブ
\n 改行
\r 復帰
\f 改ページ
\v 垂直タブ (それが何であっても)
(訳注: これは使えないように見える)
\b バックスペース
\a アラーム (ベル)
\e エスケープ
\033 8 進数で表した文字
\x1b 16 進数で表した文字
\c[ コントロール文字
\l 次の文字を小文字にする
\u 次の文字を大文字にする
\L \E まで小文字にする
\U \E まで大文字にする
\E 変更の終わり
\Q \E まで正規表現のメタ文字をクォートする
パターンはさらに、正規表現として展開が行なわれます。これは、変数が展開さ れた後の 2 回目のパスで行なわれるので、変数に正規表現を含めておき、パター ンの中へ展開することができます。もし、そうしたくないのであれば、\Q を使 うと変数の内容を文字どおりに展開することができます。
上記のものを除けば、複数の段階を踏んで展開が行なわれることはありません。 特に、シェルのプログラマの期待とは裏腹に、バッククォートはダブルクォート の中では展開されませんし、シングルクォートがダブルクォートの中で使われて も、変数の展開を妨げることはありません。
open(TTY, '/dev/tty');
<TTY> =~ /^y/i && foo(); # 要望により foo を実行
if (/Version: *([0-9.]*)/) { $version = $1; }
next if m#^/usr/spool/uucp#;
# 安上がりな grep
$arg = shift;
while (<>) {
print if /$arg/o; # 1 度だけコンパイル
}
if (($F1, $F2, $Etc) = ($foo =~ /^(\S+)\s+(\S+)\s*(.*)/))
最後の例は、$foo を最初の 2 つの単語と行の残りに分解し、$F1 と $F2 と
$Etc に代入しています。変数に代入されれば、すなわちパターンがマッチすれ
ば、if の条件が真となります。
/g 修飾子は、グローバルなパターンマッチを指定するもので、文字列の中で可
能な限りたくさんマッチを行ないます。この動作は、コンテキストに依存します。
リストコンテキストでは、正規表現内のすべての括弧付けされたものにマッチし
た部分文字列全部のリストが返されます。括弧がなければ、パターン全体を括弧
で括っていたかのように、すべてのマッチした文字列のリストが返されます。
スカラコンテキストでは、m//g は文字列内で繰り返しを行ない、マッチするご
とに「真」を返し、最終的にマッチしなくなったときに「偽」を返します。(言
い換えると、前回止まった場所を覚えていて、その場所から検索を再開するとい
うことです。文字列の現在の検索位置は、関数 pos() を使って知ることができ
ます。See section 組み込み関数,を参照してください。)いかなる方法でも、対象の文
字列を変更すると、検索位置は先頭にリセットされます。
例:
# リストコンテキスト
($one,$five,$fifteen) = (`uptime` =~ /(\d+\.\d+)/g);
# スカラコンテキスト
$/ = ""; $* = 1; # Perl 5 では、$* は使わないほうがよい
while ($paragraph = <>) {
while ($paragraph =~ /[a-z]['")]*[.!?]+['")]*\s/g) {
$sentences++;
}
}
print "$sentences\n";
$foo = q!I said, "You said, 'She said it.'"!;
$bar = q('This is it.');
$_ .= qq
(*** The previous line contains the naughty word "$1".\n)
if /(tcl|rexx|python)/; # :-)
$today = qx{ date };
詳しくは「See section I/O 演算子,」の節を参照してください。
split(' ', q/STRING/);
と完全に同じになります。
よく行なわれる例としては:
use POSIX qw( setlocale localeconv ); @EXPORT = qw( foo bar baz );というものがあります。
s/\bgreen\b/mauve/g; # wintergreen は変更しない
$path =~ s|/usr/bin|/usr/local/bin|;
s/Login: $foo/Login: $bar/; # 実行時パターン
($foo = $bar) =~ s/this/that/;
$count = ($paragraph =~ s/Mister\b/Mr./g);
$_ = 'abc123xyz';
s/\d+/$&*2/e; # 'abc246xyz' となる
s/\d+/sprintf("%5d",$&)/e; # 'abc 246xyz'
s/\w/$& x 2/eg; # 'aabbcc 224466xxyyzz'
s/%(.)/$percent{$1}/g; # パーセントエスケー
# プを変更; /e なし
s/%(.)/$percent{$1} || $&/ge; # 式となるので /e
s/^=(\w+)/&pod($1)/ge; # 関数呼び出しを使う
# /e はネスト可能;
# $_ に単純に埋め込まれた変数を展開する
s/(\$\w+)/$1/eeg;
# C コメントの削除
$program =~ s {
/\* (?# 開始区切り文字にマッチ)
.*? (?# 最短一致でマッチ)
\*/ (?# 終了区切り文字にマッチ)
} []gsx;
s/^\s*(.*?)\s*$/$1/; # 空白の切り詰め
s/([^ ]*) *([^ ]*)/$2 $1/; # 最初の 2 語の入れ替え
最後の例で \ の代わりに $ を使っているのに注意してください。sed と違って、
\<数字> の形式はパターンの方でのみ使用できます。その他の場所では、$<数字
> を使います。
ときには、/g を付けるだけでは、すべてを変更することができないことがあり
ます。2 つ例を示します:
# 整数の適切な位置にコンマを入れる 1 while s/(.*\d)(\d\d\d)/$1,$2/g; # perl4 1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/g; # perl5 # タブを 8 カラムのスペースに展開 1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e;
例: tr[A-Z][a-z] や tr(+-*/)/ABCD/。オプションには、
$ARGV[1] =~ tr/A-Z/a-z/; # 小文字に統一
$cnt = tr/*/*/; # $_ 内の * を数える
$cnt = $sky =~ tr/*/*/; # $sky 内の * を数える
$cnt = tr/0-9//; # $_ 内の数字を数える
tr/a-zA-Z//s; # bookkeeper -> bokeper
($HOST = $host) =~ tr/a-z/A-Z/;
tr/a-zA-Z/ /cs; # 英字以外を 1 つの
# スペースに変換する
tr [\200-\377]
[\000-\177]; # 8th bit 目を削除
変換テーブルはコンパイル時に作られるので、SEARCHLIST も REPLACEMENTLIST
もダブルクォート展開の対象とはなりません。変数を使いたい場合には、eval()
を使わなければならないということです:
eval "tr/$oldlist/$newlist/"; die $@ if $@; eval "tr/$oldlist/$newlist/, 1" or die $@;
Go to the first, previous, next, last section, table of contents.