Quelle est la différence en Perl lors du passage d’une variable dans une expression régulière entre $ variable et $ {variable}

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

Question

Je suis en train de passer en revue certains déclencheurs ClearCase écrits en Perl. J'ai remarqué que dans certaines expressions rationnelles, les variables sont passées directement ou avec leur nom entre accolades.

Par exemple, j'ai la ligne de code suivante dans un déclencheur:

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

$ composant , $ phase , $ code_automatisé , $ racine_projet sont toutes des variables.

Pourquoi certains sont-ils passés en tant que $ variable et d'autres en tant que $ {variable} dans l'expression régulière?

Cela vient-il de la façon dont ils ont été initialisés?

Voici la ligne de code qui les initialise:

($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+';
}
Était-ce utile?

La solution

Si vous transmettez la variable sous la forme $ {name}, cela délimite explicitement l'emplacement de la fin du nom de la variable et celui du reste de la chaîne entre guillemets. Par exemple, dans votre code:

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

Sans les délimiteurs {} :

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

Notez que la variable $ composant (vous pouvez vous y référer de toute façon) sera interprétée à tort comme $ composant_ à cause du tiret bas de fin de l'expression régulière.

Autres conseils

Tout d'abord, cela s'appelle une interpolation de chaîne. Une bonne raison de l’utiliser dans ce cas est d’empêcher que $ project_root ne soit interprété comme $ project_root_ (notez le tiret de soulignement final). Cela rend le nom de la variable explicite, au lieu de laisser les règles d'interpolation plus compliquées.

Voir perldata pour plus d'informations sur l'interpolation et perlre et perlop sur les particularités de l'interpolation dans les opérateurs d'expression régulière.

Comme mentionné ci-dessus, il permet de délimiter les noms de variables. Trop d'accolades rendent encore plus difficiles les expressions régulières déjà difficiles. Les accolades ont leurs propres utilisations d’expression rationnelle (pour limiter le nombre de correspondances d’un motif). Je vous recommande d'utiliser le modificateur regexp / x et de réécrire votre expression rationnelle de la manière suivante:

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top