Regex problem

hello !

i have a problem with ruby’s gsub function:

i want to substitute one \ with two \

in irb this looks as follows:

x = ‘/\’
“/\”
puts x
/
nil

this works

puts x.gsub(/\/,‘a’)
/a
nil

the following is the problem:

puts x.gsub(/\/,‘\\’)
/
nil

why not /\ ?

puts x.gsub(/\/,‘a’).gsub(/a/,‘\\’)
/
nil

why not /\ ?

puts x.gsub(/\/,‘\\\’)
/\
nil

why ???

thanks in advance,

peter

i want to substitute one \ with two \\

It's in the faq, see

   http://www.rubycentral.com/faq/rubyfaq-9.html#ss9.18

Regexp.quote('\\') escapes a backslash.

It gets trickier if you're using sub and gsub, Say you write gsub(/\\/,
'\\\\'), hoping to replace each backslash with two. The second argument is
converted to '\\' in syntax analysis. When the substitution occurs, the
regular expression engine converts this to '\', so the net effect is to
replace each single backslash with another single backslash. You need to
write gsub(/\\/, '\\\\\\')!

However, using the fact that \& contains the matched string, you could also
write gsub(/\\/, '\&\&').

If you use the block form of gsub, i.e. gsub(/\\/){'\\\\'}, the string for
substitution is analyzed only once (during the syntax pass) and the result
is what you intended.

Guy Decoux

Thank you for your help !

This way i was able to adapt my sql.rb file of the ruby DBI database
interface.

I think my addition (the gsub(/\/,‘&&’)) is needed for escaping
ruby-strings really reliable.
Currently i do a web-analysis with ruby and postgresql and had many
postgresql Errors because of Referrers ending with ""

## Quote strings appropriately for SQL statements
def quote(value)
  case value
  when String

value = value.gsub(/\/,‘&&’).gsub(/‘/, "’‘") # ’ (for ruby-mode)
"’#{value}‘"
when NilClass
“NULL”
when TrueClass
“‘t’”
when FalseClass
“‘f’”
when Array
value.collect { |v| quote(v) }.join(", ")
when DBI::Date, DBI::Time, DBI::Timestamp, ::Date, ::Time
"’#{value.to_s}'"
else
value.to_s
end
end

Did i miss another possibility to quote my SQL correctly or was this part
really missing in the DBI ?

Peter Schueller

···

----- Original Message -----
From: “ts” decoux@moulon.inra.fr
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Cc: ruby-talk@ruby-lang.org
Sent: Tuesday, October 01, 2002 1:36 PM
Subject: Re: regex problem

i want to substitute one \ with two \

It’s in the faq, see

http://www.rubycentral.com/faq/rubyfaq-9.html#ss9.18

Regexp.quote(‘\’) escapes a backslash.

It gets trickier if you’re using sub and gsub, Say you write gsub(/\/,
‘\\’), hoping to replace each backslash with two. The second argument is
converted to ‘\’ in syntax analysis. When the substitution occurs, the
regular expression engine converts this to '', so the net effect is to
replace each single backslash with another single backslash. You need to
write gsub(/\/, ‘\\\’)!

However, using the fact that & contains the matched string, you could
also
write gsub(/\/, ‘&&’).

If you use the block form of gsub, i.e. gsub(/\/){‘\\’}, the string for
substitution is analyzed only once (during the syntax pass) and the result
is what you intended.

Guy Decoux

I think my addition (the gsub(/\\/,'\&\&')) is needed for escaping
ruby-strings really reliable.

Well, probably it's best to see directly with the author of DBI

Guy Decoux