2009-05-01 3 views
6

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

ответ

7

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

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

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

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

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

+0

ОК, так что я лучше использовать $ {переменная} все время, а затем. Нет? –

+0

Я предлагаю только там, где это необходимо - вы должны знать имена своих переменных, поэтому, если они вызовут конфликт, тогда сделайте это. Делать это повсюду может быть шумно –

+0

ОК, спасибо! Я получил ответы. :-) –

1

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

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

1

Как уже упоминалось выше, существует возможность разграничения имен переменных. Слишком много фигурных скобок еще труднее усложняют регулярные выражения. В фигурных скобках используется собственное использование регулярных выражений (чтобы ограничить количество совпадений шаблона). Я рекомендовал бы использовать регулярное выражение/х модификатор, и переписать регулярное выражение как:

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)