2011-09-26 37 views
5

我在替換文本中跟隨一個文字後反向引用出現問題。我曾嘗試以下:在perl中,替換文本反向引用後面跟着數字文字

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 

首先當然是導致問題,因爲$ {} varWithLeadingNumber以數字開頭,但我認爲\g{1}結構在我的第二次嘗試上面應該解決這個問題。我使用的是perl 5.12.4。

+4

你確定你的問題不在shell嗎?除了收集shell變量的部分之外,我會將腳本用單引號括起來,以減少需要擔心的反斜槓的數量。 –

+0

我剛剛試過,例如'perl -pi -e's /( foo <\/tag1> \ n \ s * )[^ \ n] *(<\/tag2>)/ \ g {1} 25 \ g {2}/'file.xml',結果是一樣的。替換文本最終成爲'g {1} 25g {2}'。 – jonderry

回答

18

使用\1,\2等在替換表達式中是錯誤的。 \1是一個正則表達式模式,意思是「匹配匹配的第一個捕捉」,這在替換表達式中沒有意義。正則表達式模式不應該在正則表達式之外使用! $1,$2等是你應該在那裏使用。

固定\1後,你有

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

這麼說,我覺得varWithLeadingNumber應該是一個shell變量?如果它是一個Perl變量,你不應該有任何問題。如果您在外殼內插varWithLeadingNumber,這個問題可以用

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

注意,您將有問題,如果$ varWithLeadingNumber包含「$」,是固定的「@」,「\」或「/」,所以您可能需要使用命令行參數而不是插值。

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

您也可以使用環境變量。

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

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

如果你確實有一個\1

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

就可以避免該問題的許多方面,包括

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

這是有效的,如果我做'perl -0pi -e's /( foo <\/tag1> \ n \ s * )[^ \ n] *(<\/tag2>)/ $ {1}'$ {varWithLeadingNumber}'$ {2} /'file.xml。謝謝。 – jonderry

+0

僅適用於'$ varWithLeadingNumber'的有限值。我建議反對。 – ikegami