¿Cuál es la diferencia en Perl cuando se pasa una variable en una expresión regular entre usar $ variable y $ {variable}

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

Pregunta

Estoy revisando algunos desencadenadores de ClearCase escritos en Perl. He notado que en algunas expresiones regulares, las variables se pasan directamente o con sus nombres entre llaves.

Por ejemplo, tengo la siguiente línea de código en un activador:

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

$ component , $ phase , $ automaticdigit , $ project_root son todas variables.

¿Por qué algunos se pasan como $ variable y otros se pasan como $ {variable} en la expresión regular?

¿Viene de cómo se inicializan?

Aquí está la línea de código que los inicializa:

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

Solución

Si pasa la variable como $ {nombre}, esto delimita explícitamente dónde está el final del nombre de la variable y donde comienza el resto de la cadena entre comillas. Por ejemplo, en su código:

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

Sin los delimitadores {} :

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

Tenga en cuenta que la variable $ component (puede referirse a ella de cualquier manera) se interpretará erróneamente como $ component_ debido al subrayado final en la expresión regular.

Otros consejos

Primero, esto se llama interpolación de cadenas. Una buena razón para usarlo en este caso es evitar que $ project_root se interprete como $ project_root_ (tenga en cuenta el subrayado final). Hace explícito el nombre de la variable, en lugar de dejarlo en las reglas de interpolación más complicadas.

Consulte perldata para obtener más información sobre la interpolación, y perlre y perlop sobre las peculiaridades de la interpolación dentro de los operadores de expresiones regulares.

Como se mencionó anteriormente, está ahí para delimitar nombres de variables. Demasiadas llaves que hacen que las expresiones regulares ya difíciles sean aún más difíciles. Las llaves tienen su propio uso de expresiones regulares (para limitar el número de veces que un patrón coincide). Recomendaría usar el modificador de expresiones regulares / x, y reescribir su expresión regular 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top