why gsub! doesn't work in my script

L

Li Chen

Hi all,

I want to search one pattern in a file line by line and replace it with
new pattern one. But it doesn't work. I cannot change the old pattern
into the new one using gsub! Is there any problem with my script?

Thanks,

Li




################Ruby script##############

#create a regular expression and its replacement

r1_obj=Regexp.escape('1.000000\$P1G\1.000000') #pattern
r2_obj=Regexp.escape('2.000000\$P1G\2.000000') #replacement


DATA.each_line do |line|
if line.match(r1_obj)
line.gsub!(r1_obj, r2_obj) #
puts line
end
end




__END__

test1.001
K:\flow\test\test1.001
xxx\1.000000\$P1G\1.000000\xxx
yyyy\1.000000\$P1G\1.000000\xxx
test1.002
K:\flow\test\test1.002
xxx\1.000000\$P1G\1.000000\xxx
yyyy\1.000000\$P1G\1.000000\xxx
test1.003
K:\flow\test\test1.003
xxx\1.000000\$P1G\1.000000\xxx
yyyy\1.000000\$P1G\1.000000\xxx

####screen output###########

xxx\1.000000\$P1G\1.000000\xxx
yyyy\1.000000\$P1G\1.000000\xxx
xxx\1.000000\$P1G\1.000000\xxx
yyyy\1.000000\$P1G\1.000000\xxx
xxx\1.000000\$P1G\1.000000\xxx
yyyy\1.000000\$P1G\1.000000\xxx
 
L

Li Chen

Jason said:
Backslash ( \ ) is the escape character. If you want to match \ itself,
you
need to escape it ( \\ ). So try these regex's:

r1_obj=Regexp.escape('1.000000\\$P1G\\1.000000') #pattern
r2_obj=Regexp.escape('2.000000\\$P1G\\2.000000') #replacement

Jason

Thanks, but the replacement still doesn't work.

It is my understanding that Regexp#escape method should do the magic
work for me.

Li
 
K

Ken Bloom

Hi all,

I want to search one pattern in a file line by line and replace it with
new pattern one. But it doesn't work. I cannot change the old pattern
into the new one using gsub! Is there any problem with my script?

Thanks,

Li




################Ruby script##############

#create a regular expression and its replacement

r1_obj=Regexp.escape('1.000000\$P1G\1.000000') #pattern
r2_obj=Regexp.escape('2.000000\$P1G\2.000000') #replacement


DATA.each_line do |line|
if line.match(r1_obj)
line.gsub!(r1_obj, r2_obj) #
puts line
end
end

Regexp.escape takes a string as a parameter, and returns a string as its
return value. When you use that string in your Regexp.escape call, you
convert it into something that no longer matches the text in your file,
and when you use the returned string in the gsub call, it tries to match
it literally.

irb(main):003:0> "...".gsub(Regexp.escape("."),"x")
=> "..."
irb(main):004:0> "...".gsub(".","x")
=> "xxx"
irb(main):005:0> "...".gsub(Regexp.new(Regexp.escape(".")),"x")
=> "xxx"
 
L

Li Chen

1) what is the best scenario to use Regexp.escape?

2) I modify my codes and I get the expected results. But the odd is that
I have to use 3 backslashes before the 2nd 2. How to explain this.

Thanks,

Li


DATA.each_line do |line|

if line=~/1\.000000\\\$P1G\\1\.000000/
line.gsub!(/1\.000000\\\$P1G\\1\.000000/,
'2.000000\\\$P1G\\\2.000000')
puts line
end
end

###same DATA as the first post##

####screen output####

ruby FC500_3.rb
xxx\2.000000\$P1G\2.000000\xxx
yyyy\2.000000\$P1G\2.000000\xxx
xxx\2.000000\$P1G\2.000000\xxx
yyyy\2.000000\$P1G\2.000000\xxx
xxx\2.000000\$P1G\2.000000\xxx
yyyy\2.000000\$P1G\2.000000\xxx
 
J

james.d.masters

R

Rick DeNatale

1) what is the best scenario to use Regexp.escape?

2) I modify my codes and I get the expected results. But the odd is that
I have to use 3 backslashes before the 2nd 2. How to explain this.

Thanks,

Li


DATA.each_line do |line|

if line=~/1\.000000\\\$P1G\\1\.000000/
line.gsub!(/1\.000000\\\$P1G\\1\.000000/,
'2.000000\\\$P1G\\\2.000000')
puts line
end
end

How about this:

# In single quoted strings you only escape \ and '
# You can interpolate into a pattern literal.
pat = /#{Regexp.escape('1.000000\$P1G\1.000000')}/
# No need for Regexp.escape here since the second parameter to gsub!
# is a string, not a pattern.
sub = '2.000000\\$P1G\\2.000000')

And then either:

if line =~ pat
line.gsub!(pat,sub)
puts line
end

or just

puts line if line.gsub!(pat,sub)

since gsub! returns nil if no substitution was performed and the
string if it was.
 
K

Ken Bloom

1) what is the best scenario to use Regexp.escape?

You use Regexp.escape when you're building up a regular expression
programmatically as a String, and using Regexp.new to turn it into a
regular expression. In that case, all of the control codes in the string
will be interpreted, so if you have a string that needs to be matched
literally, then you use Regexp.escape to escape it first. This is also
the case when using variable interpolation.

airb(main):001:0> a="..."
=> "..."
irb(main):002:0> /#{a}/
=> /.../
irb(main):003:0> /#{Regexp.escape(a)}/
=> /\.\.\./

--Ken
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top