我正在审查一些用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+';
}
答案 0 :(得分:7)
如果将变量作为$ {name}传递,则会明确界定变量名称的结尾位置,以及引用字符串的其余部分的开始位置。例如,在您的代码中:
if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
没有{}
分隔符:
if ($baseline !~ /^$component_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
请注意,由于正则表达式中的尾随下划线,变量$ component(您可以以任何方式引用它)将被误解为$ component_。
答案 1 :(得分:1)
首先,这称为字符串插值。在这种情况下使用它的一个很好的理由是防止$ project_root被解释为$ project_root_(注意尾随下划线)。它明确了变量名称,而不是将其留给更复杂的插值规则。
有关插值的详细信息,请参阅perldata,有关正则表达式运算符中插值特性的perlre和perlop。
答案 2 :(得分:1)
如上所述,它用于分隔变量名称。太多的花括号使得已经很难的正则表达式变得更难。大括号有自己的正则表达式用法(限制模式匹配的次数)。我建议使用regexp / x修饰符,并将regexp重写为:
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)