$ variableと$ {variable}を使用して正規表現で変数を渡すときのPerlの違いは何ですか
質問
Perlで記述されたClearCaseトリガーの一部を確認しています。一部の正規表現では、変数がそのまま渡されるか、名前が中括弧で囲まれていることに気付きました。
たとえば、トリガーには次のコード行があります:
if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
$baseline !~ /^${project_root}_$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/)
$ component
、 $ phase
、 $ automateddigit
、 $ project_root
はすべて変数です。
正規表現で $ variable
として渡されるものと $ {variable}
として渡されるものがあるのはなぜですか?
初期化の方法から来ていますか?
これらを初期化するコード行は次のとおりです。
($project = $ENV{CLEARCASE_PROJECT}) =~ s/\@.*$//;
($component = $ENV{CLEARCASE_COMPONENT}) =~ s/\@.*$//;
($project_root, $phase) = ($project =~ /^(.*)_(R\d+.*)$/);
exit(0) if (! $phase);
$phase .= ".0" if ($phase =~ /^R\d+$/);
$automateddigit = '';
$istream = `cleartool desc -fmt "%[istream]p" project:$ENV{CLEARCASE_PROJECT}`;
$componentlist = `cleartool desc -fmt "%[components]Cp" stream:$ENV{CLEARCASE_STREAM}`;
$componentsnbr = split(',', $componentlist);
if ($componentsnbr > 1) {
$automateddigit .= '\\.\\d+';
}
解決
変数を$ {name}として渡すと、変数名の末尾と引用符で囲まれた文字列の残りの部分が明示的に区切られます。たとえば、コード内で:
if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
{}
区切り文字なし:
if ($baseline !~ /^$component_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
変数$ component(どちらの方法でも参照できます)は、正規表現の末尾にアンダースコアがあるため、誤って$ component_と解釈されることに注意してください。
他のヒント
まず、これは文字列補間と呼ばれます。この場合に使用する正当な理由の1つは、$ project_rootが$ project_root_として解釈されないようにすることです(末尾のアンダースコアに注意してください)。変数名をより複雑な補間規則に任せるのではなく、明示的にします。
補間の詳細についてはperldataを、正規表現演算子内の補間の特性についてはperlreとperlopを参照してください。
上記のように、変数名を区切るためにあります。中括弧が多すぎると、すでに難しい正規表現がさらに難しくなります。中括弧には、独自の正規表現が使用されます(パターンが一致する回数を制限するため)。正規表現/ x修飾子を使用することをお勧めします。正規表現を次のように書き換えます。
if ($baseline !~ /^$component # Start with $component
_ # then an underscore
(|.*_) # Then nothing, or anything followed by an underscore
$phase # ...
\.\d+ # ...
(| # Then optionally:
[a-z]| # lower alpha
-\d+| # or ...
$automateddigit
)
$/x &&
$baseline !~ /^$project_root
_
$phase
\.\d+
(|
[a-z]|
-\d+|
$automateddigit
)$/x)