[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

why gsub! doesn't work in my script

Li Chen

6/11/2007 1:34:00 PM

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

--
Posted via http://www.ruby-....

7 Answers

Li Chen

6/11/2007 2:09:00 PM

0

Jason Roelofs wrote:
> 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


--
Posted via http://www.ruby-....

Ken Bloom

6/11/2007 3:08:00 PM

0

On Mon, 11 Jun 2007 22:34:16 +0900, Li Chen wrote:

> 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"



--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Li Chen

6/11/2007 5:49:00 PM

0

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




--
Posted via http://www.ruby-....

james.d.masters

6/11/2007 7:48:00 PM

0

On Jun 11, 10:49 am, Li Chen <chen_...@yahoo.com> wrote:
> 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.

This is because the 2nd string can use \1, \2, etc... as a replacement
for a previous match in the 1st string (matches are specified in the
1st string in parentheses). This topic was discussed here a few days
ago:

http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/78325335e89ce302/c99e5dda10c017fb#c99e5d...

Rick DeNatale

6/11/2007 8:03:00 PM

0

On 6/11/07, Li Chen <chen_li3@yahoo.com> wrote:
> 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.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Li Chen

6/11/2007 8:30:00 PM

0

Rick,

Thank you very much. Your codes are the simplest and most concise for
me.


Li

--
Posted via http://www.ruby-....

Ken Bloom

6/12/2007 1:08:00 AM

0

On Tue, 12 Jun 2007 02:49:10 +0900, Li Chen wrote:

> 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

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...