2011-09-26 8 views
5

Ho problemi con un riferimento alla restrizione nel testo di sostituzione seguito da un valore letterale. Ho provato quanto segue:In perl, backreference nel testo di sostituzione seguito da un valore letterale numerico

perl -0pi -e "s/(<tag1>foo<\/tag1>\n\s*<tag2>)[^\n]*(<\/tag2>)/\1${varWithLeadingNumber}\2/" file.xml 
perl -0pi -e "s/(<tag1>foo<\/tag1>\n\s*<tag2>)[^\n]*(<\/tag2>)/\g{1}${varWithLeadingNumber}\g{2}/" file.xml 

Il primo, naturalmente, provoca problemi perché $ {} varWithLeadingNumber inizia con un numero, ma ho pensato che il \g{1} costrutto nel mio secondo tentativo in precedenza avrebbe dovuto risolvere questo problema. Sto usando perl 5.12.4.

+4

Sei sicuro che il tuo problema non sia con la shell? Allegherei lo script tra virgolette singole eccetto per la parte che raccoglie le variabili della shell, giusto per ridurre il numero di backslash di cui preoccuparsi. –

+0

Ho appena provato, per esempio, 'perl -0pi -e 's/( pippo <\/tag1> \ n \ s * ) [^ \ n] * (<\/tag2>)/\ g {1} 25 \ g {2}/'file.xml', e il risultato è stato lo stesso. Il testo sostitutivo finisce con "g {1} 25g {2}'. – jonderry

risposta

18

L'utilizzo di \1, \2, ecc. Nell'espressione di sostituzione è errato. \1 è un modello di espressione regolare che significa "corrisponde a ciò che corrisponde alla prima acquisizione" che non ha senso in un'espressione sostitutiva. I modelli di espressioni regolari non dovrebbero essere usati al di fuori delle espressioni regolari! $1, $2, ecc. È ciò che dovresti usare lì.

Dopo aver fissato \1, avete

perl ... -e'... s/.../...$1$varWithLeadingNumber.../ ...' 

Detto questo, penso che varWithLeadingNumber si suppone essere una variabile di shell? Non dovresti avere problemi se si tratta di una variabile Perl. Se hai il guscio interpolare varWithLeadingNumber, il problema può essere risolto utilizzando

perl ... -e"... s/.../...\${1}${varWithLeadingNumber}.../ ..." 

noti che si avranno problemi se $ varWithLeadingNumber contiene "$", "@", "\" o "/", così potresti voler usare un argomento da linea di comando invece dell'interpolazione.

perl ... -pe' 
    BEGIN { $val = shift; } 
    ... s/.../...$1$val.../ ... 
' "${varWithLeadingNumber}" 

È anche possibile utilizzare una variabile di ambiente.

export varWithLeadingNumber 
perl ... -pe's/.../...$1$ENV{varWithLeadingNumber}.../' 

o

varWithLeadingNumber=varWithLeadingNumber \ 
    perl ... -pe's/.../...$1$ENV{varWithLeadingNumber}.../' 

Se si ha avuto un \1

s/...\1.../.../ 

è possibile evitare il problema di un certo numero di modi tra cui

s/...(?:\1).../.../ 
+0

Funziona se faccio 'perl -0pi -e 's/( pippo <\/tag1> \ n \ s * ) [^ \ n] * (<\/tag2>)/$ {1}' $ {varWithLeadingNumber} '$ {2}/'file.xml. Grazie. – jonderry

+0

Solo per valori limitati di '$ varWithLeadingNumber'. Raccomando contro quello. – ikegami

Problemi correlati