tags:

views:

62

answers:

2

Consider the following string which is a C fragment in a file:

strcat(errbuf,errbuftemp);

I want to replace errbuf (but not errbuftemp) with the prefix G-> plus errbuf. To do that successfully, I check the character after and the character before errbuf to see if it's in a list of approved characters and then I perform the replace.

I created the following Ruby file:

line = " strcat(errbuf,errbuftemp);"  
item = "errbuf"  
puts line.gsub(/([ \t\n\r(),\[\]]{1})#{item}([ \t\n\r(),\[\]]{1})/, "#{$1}G\->#{item}#{$2}")

Expected result:

strcat(G->errbuf,errbuftemp);

Actual result

strcatG->errbuferrbuftemp);

Basically, the matched characters before and after errbuf are not reinserted back with the replace expression.

Anyone can point out what I'm doing wrong?

+2  A: 

Because you must use syntax gsub(/.../){"...#{$1}...#{$2}..."} or gsub(/.../,'...\1...\2...').

Here was the same problem: http://stackoverflow.com/questions/3829273/werid-same-expression-yield-different-value-when-excuting-two-times-in-irb/

The problem is that the variable $1 is interpolated into the argument string before gsub is run, meaning that the previous value of $1 is what the symbol gets replaced with. You can replace the second argument with '\1 ?' to get the intended effect. (Chuck)

Nakilon
Right on, looked through the thread you provided and came up with: puts line.gsub(/([ \t\n\r(),\[\]]{1})#{item}([ \t\n\r(),\[\]]{1})/){"#{$1}G\->#{item}#{$2}"}
Theo
A: 

I think part of the problem is the use of gsub() instead of sub().

Here's two alternates:

str = 'strcat(errbuf,errbuftemp);'

str.sub(/\w+,/) { |s| 'G->' + s } # => "strcat(G->errbuf,errbuftemp);"
str.sub(/\((\w+)\b/, '(G->\1') # => "strcat(G->errbuf,errbuftemp);"
Greg
If I reverse errbuf and errbuftemp in the input string, your code will append G-> to errbuftemp rather than errbuf. I'm looking to ignore errbuftemp and process errbuf only - hence the peeking at the character before and after in my original regex.Appreciate the fact that you took some time to provide an answer, though.
Theo
Ah, well that wasn't a prerequisite in the question. I had a sample that does follow errbuf. Check the #1 edit and you should see it.
Greg