【问题标题】:What is the difference in Perl when passing a variable in a regular expression between using $variable and ${variable}在使用 $variable 和 ${variable} 之间在正则表达式中传递变量时,Perl 有什么区别
【发布时间】:2009-05-01 10:12:25
【问题描述】:

我正在审查一些用 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+';
}

【问题讨论】:

    标签: regex perl syntax triggers clearcase


    【解决方案1】:

    如果您将变量作为 ${name} 传递,这将明确界定变量名称的结尾在哪里,以及引用字符串的其余部分从哪里开始。例如,在您的代码中:

    if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
    

    没有{} 分隔符:

    if ($baseline !~ /^$component_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
    

    请注意,由于正则表达式中的尾随下划线,变量 $component(您可以以任何方式引用它)将被误解为 $component_。

    【讨论】:

    • 好的,那么我最好一直使用 ${variable}。没有?
    • 我建议仅在必要时使用 - 您应该注意变量的名称,如果它们会导致冲突,请执行此操作。在任何地方都这样做会很吵
    • 好的,谢谢!我得到了我的答案。 :-)
    【解决方案2】:

    首先,这称为字符串插值。在这种情况下使用它的一个很好的理由是防止 $project_root 被解释为 $project_root_ (注意结尾的下划线)。它明确了变量名称,而不是将其留给更复杂的插值规则。

    有关插值的更多信息,请参阅 perldata,有关正则表达式运算符中插值的特性,请参阅 perlre 和 perlop。

    【讨论】:

      【解决方案3】:

      如上所述,它用于分隔变量名称。太多的花括号会使已经很困难的正则表达式变得更加困难。花括号有自己的正则表达式用途(限制模式匹配的次数)。我建议使用正则表达式 /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)
      

      【讨论】:

        猜你喜欢
        • 2019-11-16
        • 2013-07-22
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        • 1970-01-01
        • 2023-04-07
        • 2021-08-19
        • 1970-01-01
        相关资源
        最近更新 更多