在perl中,替换文本中的后向引用后跟数值文字

时间:2011-09-26 18:23:58

标签: regex 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。

1 个答案:

答案 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).../.../