Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
873 views
in Technique[技术] by (71.8m points)

regex - In perl, backreference in replacement text followed by numerical literal

I'm having trouble with a backreference in my replacement text that is followed by a literal. I have tried the following:

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

The first of course causes problems because ${varWithLeadingNumber} begins with a number, but I thought the g{1} construct in my second attempt above was supposed to solve this problem. I'm using perl 5.12.4.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Using 1, 2, etc in the replacement expression is wrong. 1 is a regular expression pattern that means "match what the first capture matched" which makes no sense in a replacement expression. Regular expression patterns should not be used outside of regular expressions! $1, $2, etc is what you should be using there.

After fixing 1, you have

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

That said, I think varWithLeadingNumber is supposed to be a shell variable? You shouldn't have any problems if it's a Perl variable. If you're having the shell interpolate varWithLeadingNumber, the problem can be fixed using

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

Note that you will have problems if $varWithLeadingNumber contains "$", "@", "" or "/", so you might want to use a command line argument instead of interpolation.

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

You could also use an environment variable.

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

or

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

If you did have a 1

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

you can avoid the problem a number of ways including

s/...(?:1).../.../

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...