James Gray
11/3/2004 6:46:00 PM
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