Dumb str.sub question

I feel really dumb asking this, but I just can’t seem to figure it out.

I am trying to parse some text for use in a mysql insert statement. That
being the case, I need to escape out quote characters.

If str= “isn’t stands for is not”, what I want is a string with “isn’t
stands for is not”

At first I thought, sure, no problem!! But I can’t get it. I’ve tried the
following:

irb:1> str = "isn’t stands for is not"
irb:2> str.sub( ‘’’, ‘’’ ) --> “isn’t stands for is not” (expected)
irb:3> str.sub( ‘’’, ‘\’’ ) --> unterminated string (expected)
irb:4> str.sub( ‘’’, ‘\’ ) --> “isnt stands for is nott stands for is
not” (huh? Why this wierd double take?)
irb:5> str.sub( ‘’’ ){ |m| m = “’” } --> “isn’t stands for is not”
(expected)
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)

So, my quesitons are:

  1. How do I do my escape character substituion
  2. Why did #4 and #6 behave as they did?

Thanks.

···

Gift-shop online from the comfort of home at MSN Shopping! No crowds, free
parking. http://shopping.msn.com

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

···

On Thu, Nov 27, 2003 at 03:08:17AM +0900, Orion Hunter wrote:

str = "isn’t stands for is not"
puts str.sub(/’/) { “\’” } #=> isn’t stands for is not

After execution, irb prints an #inspect on the resulting object.

-austin

···


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.26
* 13.48.12

In article 20031126184634.GB1520@mulan.thereeds.org,

···

Mark J. Reed markjreed@mail.com wrote:

irb(main):006:0> str.sub(/'/) { ‘\'’ }
=> “isn\'t stands for is not”

Sometimes it is useful to pick your quotes carefully e.g.

str.sub(/'/) { ‘\'’ }

as you’re quoting a single quote then using double quotes saves a \

str.sub(/‘/) { "\’" }

Mike


mike@stok.co.uk | The “`Stok’ disclaimers” apply.
http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA
mike@exegenix.com | Fingerprint 0570 71CD 6790 7C28 3D60
http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA

Good point. I generally make a habit of using single quotes when
I’m not doing any interpolation and double-quotes when I am, but this
would be a logical place to make an exception. :slight_smile:

-Mark

···

On Wed, Nov 26, 2003 at 07:17:55PM +0000, Mike Stok wrote:

Sometimes it is useful to pick your quotes carefully e.g.

str.sub(/'/) { ‘\'’ }

as you’re quoting a single quote then using double quotes saves a \

str.sub(/‘/) { "\’" }