Qual è la differenza in Perl quando si passa una variabile in un'espressione regolare tra l'utilizzo di $ variabile e $ {variabile}
Domanda
Sto esaminando alcuni trigger ClearCase scritti in Perl. Ho notato che in alcune espressioni regolari, le variabili vengono passate in modo diretto o con i loro nomi tra parentesi graffe.
Ad esempio, ho la seguente riga di codice in un trigger:
if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
$baseline !~ /^${project_root}_$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/)
$ component
, $ phase
, $ automaticdigit
, $ project_root
sono tutte variabili.
Perché alcuni vengono passati come $ variabile
e altri passati come $ {variabile}
nell'espressione regolare?
Viene da come sono inizializzati?
Ecco la riga di codice che li inizializza:
($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+';
}
Soluzione
Se passi la variabile come $ {name}, questo delimita esplicitamente dove si trova la fine del nome della variabile e dove inizia il resto della stringa tra virgolette. Ad esempio, nel tuo codice:
if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
Senza i delimitatori {}
:
if ($baseline !~ /^$component_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
Si noti che la variabile $ componente (è possibile fare riferimento in entrambi i modi) verrà interpretata erroneamente come $ componente_ a causa del carattere di sottolineatura finale nell'espressione regolare.
Altri suggerimenti
Per prima cosa, si chiama interpolazione di stringhe. Un buon motivo per usarlo in questo caso è impedire che $ project_root venga interpretato come $ project_root_ (notare il carattere di sottolineatura finale). Rende esplicito il nome della variabile, invece di lasciarlo alle regole di interpolazione più complicate.
Vedi perldata per ulteriori informazioni sull'interpolazione e perlre e perlop sulle peculiarità dell'interpolazione all'interno degli operatori delle espressioni regolari.
Come accennato in precedenza, è lì per delimitare i nomi delle variabili. Troppe parentesi graffe rendono ancora più difficili le espressioni regolari già difficili. Le parentesi graffe hanno i loro usi regexp (per limitare il numero di volte in cui un pattern corrisponde). Consiglio di utilizzare il modificatore regexp / x e riscrivere il regexp come:
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)