我在替换文本中使用后向引用时出现问题,后面跟着文字。我尝试过以下方法:
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。
答案 0 :(得分:20)
在替换表达式中使用\1
,\2
等是错误的。 \1
是一个正则表达式模式,意思是“匹配第一个匹配的匹配”,这在替换表达式中没有意义。正则表达式模式不应该在正则表达式之外使用! $1
,$2
等是你应该在那里使用的。
修好\1
后,您有
perl ... -e'... s/.../...$1$varWithLeadingNumber.../ ...'
那就是说,我认为varWithLeadingNumber
应该是一个shell变量?如果它是Perl变量,你不应该有任何问题。如果您正在进行shell插值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).../.../