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

StackOverflow https://stackoverflow.com/questions/810876

Вопрос

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

Решение

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

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

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

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

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

Другие советы

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

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

Как упоминалось выше, он предназначен для разграничения имен переменных.Слишком много фигурных скобок делают и без того сложные регулярные выражения еще сложнее.Фигурные скобки имеют свое собственное регулярное выражение (для ограничения количества совпадений с шаблоном).Я бы рекомендовал использовать модификатор 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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top