On Nov 3, 2004, at 12:12 PM, Paul Rubel wrote: > Hi, > > I'm trying to take a string and escape a single quote if it is not > already escaped. My first thought was to look at the string and if I > see a quote without a backslash before it put the backslash there. What about: gsub(/(\\*)'/) { |m| $1.length % 2 == 0 ? $1 + "\\'" : m } > Would look-behind be an option here out of the box? Surprisingly, I don't believe Ruby yet supports lookbehind. > While I was experimenting I saw some behavior I don't understand and > am hoping someone can explain it to me: > > prubel@cornet /tmp> cat /tmp/t.rb ; ruby /tmp/t.rb > 2.times do > # replace not a slash followed by a quote with not a slash > # and an escaped quote. > puts("\\'Summer's Day".gsub(/([^\\\\])'/,"*#{$1}\\\\'*")) The above line is problematic for two reasons. First, when using the replacement string version of gsub(), your string is interpolated before the method is even called let alone before any matches are made so $1 and friends are not set. Instead, try using a \1 in a single quoted string or \\1 in a double to get the value you're after. Two, I don't understand your pattern. [^\\\\] means ONE character that is not a slash and also not a slash. It's identical to [^\\]. I think you meant to say, not two slashes, but that's a little harder to express in a regex. And what if there are three slashes? See my solution above for a different approach. > puts $1 > end > #end > \'Summe*\'*s Day > r > \'Summe*r\'*s Day > r > prubel /tmp> ruby --version > ruby 1.8.1 (2004-02-06) [i686-linux-gnu] > > > I'm confused at to why the output is different for the two > iterations? Why doesn't the r get placed in the first output? Because $1 isn't set in time for the first replacement, but it is set when the second string is built (set by the first match). Hope that helps. James Edward Gray II