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

jon*_*rry 9 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
Run Code Online (Sandbox Code Playgroud)

第一个当然会导致问题,因为$ {varWithLeadingNumber}以数字开头,但我认为\g{1}上面第二次尝试中的构造应该可以解决这个问题.我正在使用perl 5.12.4.

ike*_*ami 21

在替换表达式中使用\1,\2等是错误的.\1是一个正则表达式模式,意味着"匹配第一个捕获匹配的内容",这在替换表达式中没有意义.正则表达式模式不应该在正则表达式之外使用!$1,$2等等,你应该在那里使用.

修好后\1,你有

perl ... -e'... s/.../...$1$varWithLeadingNumber.../ ...'
Run Code Online (Sandbox Code Playgroud)

那说,我认为varWithLeadingNumber应该是一个shell变量?如果它是Perl变量,你不应该有任何问题.如果您正在进行shell插值varWithLeadingNumber,则可以使用修复问题

perl ... -e"... s/.../...\${1}${varWithLeadingNumber}.../ ..."
Run Code Online (Sandbox Code Playgroud)

请注意,如果$ varWithLeadingNumber包含"$","@","\"或"/",则会出现问题,因此您可能希望使用命令行参数而不是插值.

perl ... -pe'
   BEGIN { $val = shift; }
   ... s/.../...$1$val.../ ...
' "${varWithLeadingNumber}"
Run Code Online (Sandbox Code Playgroud)

您还可以使用环境变量.

export varWithLeadingNumber
perl ... -pe's/.../...$1$ENV{varWithLeadingNumber}.../'
Run Code Online (Sandbox Code Playgroud)

要么

varWithLeadingNumber=varWithLeadingNumber \
    perl ... -pe's/.../...$1$ENV{varWithLeadingNumber}.../'
Run Code Online (Sandbox Code Playgroud)

如果你确实有 \1

s/...\1.../.../
Run Code Online (Sandbox Code Playgroud)

你可以通过多种方式避免这个问题

s/...(?:\1).../.../
Run Code Online (Sandbox Code Playgroud)