Qual é a diferença em Perl ao passar uma variável em uma expressão regular entre usando $ variável e $ {variável}

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

Pergunta

Eu estou revendo alguns gatilhos ClearCase escritos em Perl. Tenho notado que em algumas expressões regulares, as variáveis ??são passados ??quer straighforwardly ou com seus nomes em chaves.

Por exemplo, eu tenho a seguinte linha de código em um disparador:

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

$component, $phase, $automateddigit, $project_root são todas as variáveis.

Por que alguns são passados ??como $variable e outros passados ??como ${variable} na expressão regular?

ela vem como eles são inicializados?

Aqui estão a linha de código inicializando-los:

($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+';
}
Foi útil?

Solução

Se você passar a variável como $ {name}, este delimita explicitamente onde o fim do nome da variável é, e onde o resto da string começa. Por exemplo, em seu código:

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

Sem os delimitadores {}:

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

Note que os US $ componente variável (que você possa consultá-la de qualquer forma) será interpretado como $ Component_ por causa do sublinhado à direita na expressão regular.

Outras dicas

Em primeiro lugar, isso é chamado de interpolação string. Uma boa razão para usá-lo neste caso é para evitar $ project_root de ser interpretada como $ project_root_ (note o sublinhado à direita). Ele explicita o nome da variável, em vez de deixá-lo com as regras de interpolação mais complicado.

Veja perldata para saber mais sobre a interpolação, e perlre e perlop em peculiaridades de interpolação dentro operadores de expressão regular.

Como mencionado acima, ele está lá para delimitar variáveis ??nomes. Muitas chaves faz expressões regulares já difíceis ainda mais difícil. chaves têm seus próprios usos de expressões regulares (para limitar o número de vezes que um Corresponde ao padrão). Eu recomendaria usando o regexp / x modificador, e reescrever seu regexp como:

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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top