В чем разница в Perl при передаче переменной в регулярном выражении между использованием $variable и ${variable}

Я рассматриваю некоторые триггеры ClearCase, написанные на Perl. Я заметил, что в некоторых регулярных выражениях переменные передаются либо напрямую, либо с именами в фигурных скобках.

Например, у меня есть следующая строка кода в триггере:

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+';
}

person Thomas Corriol    schedule 01.05.2009    source источник


Ответы (3)


Если вы передаете переменную как ${name}, это явно разграничивает, где находится конец имени переменной и где начинается остальная часть строки в кавычках. Например, в вашем коде:

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

Без разделителей {}:

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

Обратите внимание, что переменная $component (вы можете ссылаться на нее в любом случае) будет неправильно интерпретирована как $component_ из-за подчеркивания в конце регулярного выражения.

person 1800 INFORMATION    schedule 01.05.2009
comment
Хорошо, тогда мне лучше использовать ${variable} все время. Нет ? - person Thomas Corriol; 01.05.2009
comment
Я предлагаю только там, где это необходимо - вы должны знать имена своих переменных, поэтому, если они вызовут конфликт, сделайте это. Делать это везде может быть шумно - person 1800 INFORMATION; 01.05.2009
comment
Хорошо, спасибо ! Я получил свои ответы. :-) - person Thomas Corriol; 01.05.2009

Во-первых, это называется интерполяцией строк. Одной из веских причин для его использования в этом случае является предотвращение интерпретации $project_root как $project_root_ (обратите внимание на подчеркивание в конце). Это делает имя переменной явным, вместо того, чтобы оставить его для более сложных правил интерполяции.

Подробнее об интерполяции см. в perldata, а в perlre и perlop — об особенностях интерполяции в операторах регулярных выражений.

person Anonymous    schedule 01.05.2009

Как упоминалось выше, он предназначен для разграничения имен переменных. Слишком много фигурных скобок делает и без того сложные регулярные выражения еще более сложными. Фигурные скобки имеют свое собственное использование регулярных выражений (чтобы ограничить количество совпадений шаблона). Я бы рекомендовал использовать модификатор regexp /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)
person Craig Lewis    schedule 02.05.2009