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

Я рассматриваю некоторые триггеры 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+';
}

Ответы [ 3 ]

7 голосов
/ 01 мая 2009

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

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

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

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

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

1 голос
/ 02 мая 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)
1 голос
/ 01 мая 2009

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

См. Perldata для получения дополнительной информации об интерполяции, а также perlre и perlop об особенностях интерполяции в операторах регулярных выражений.

...