Mark J. Reed
11/26/2003 6:47:00 PM
On Thu, Nov 27, 2003 at 03:08:17AM +0900, Orion Hunter wrote:
> irb:1> str = "isn't stands for is not"
> irb:4> str.sub( '\'', '\\\' ) --> "isnt stands for is nott stands for is
> not" (huh? Why this wierd double take?)
Because of the extra processing that substution strings undergo. Within
the substitution, \& is replaced by the portion of the original string
which matched; \` by the portion before the match; and \' by the portion
after. So in your case you have this:
SEQUENCE REPLACED BY
\` isn
\& '
\' t stands for is not
> irb:6> str.sub( '\'' ){ |m| m = "\\'" } --> "isn\\'t stands for is not"
> (why did it insert TWO \s?, and not just one? I would have exected the
> first one to "escape" the second, thus giving \' as desired)
It DIDN'T insert two backslashes; it inserted one, which shows up in
the inspection of a string as two becuase the inspection uses the
double-quote syntax. If you print the string out with puts or otherwise
look into it, you'll see that there is only one backslash:
irb(main):007:0> x = str.sub( '\'' ){ |m| m = "\\'" }
=> "isn\\'t stands for is not"
irb(main):008:0> puts x
isn\'t stands for is not
=> nil
irb(main):009:0> x[2,1]
=> "n"
irb(main):010:0> x[3,1]
=> "\\"
irb(main):011:0> x[4,1]
=> "'"
By the way, you can simplify to just this:
irb(main):006:0> str.sub(/'/) { '\\\'' }
=> "isn\\'t stands for is not"
And you can also use the string form if you use the
proper number of backslashes:
irb(main):002:0> str.sub(/'/, '\\\\\'')
=> "isn\\'t stands for is not"
-Mark