From: Alexandru Popescu Date: 2006-01-19T00:56:03+09:00 Subject: Re: how to double single quote (beginner blockage) #: Gavin Kistner changed the world a bit at a time by saying (astral date: 1/18/2006 5:28 PM) :# > On Jan 18, 2006, at 7:47 AM, Alexandru Popescu wrote: >> if I have a string that contains single quote (f.e. "al'alamein") i >> would like to escape it with another single quote (=> "al''alamein"). >> >> there are cases when these strings are already escaped according to >> the above rule, so those should remain untouched > > Let's build this step by step. > > The simple case is pretty simple, using Regular Expressions. You want > to find a single quote that has characters other than a single quote > on either side, and replace it with two single quotes: > > irb(main):001:0> input = "al'alamein" > => "al'alamein" > irb(main):002:0> input.gsub( /([^'])'([^'])/, "\\1''\\2" ) > => "al''alamein" > > The above breaks if the single quote occurs at the beginning or end > of the input: > irb(main):003:0> input2 = "'Hey, it's al'alamein'" > => "'Hey, it's al'alamein'" > irb(main):004:0> input2.gsub( /([^'])'([^'])/, "\\1''\\2" ) > => "'Hey, it''s al''alamein'" > > ...so let's say that there has to be a non-single quote at either > end, OR the start/end of the string: > irb(main):005:0> input2.gsub( /(\A|[^'])'([^']|\Z)/, "\\1''\\2" ) > => "''Hey, it''s al''alamein''" > > Finally, the above handles 1 or 2 single quotes in a row correctly, > but not 3 or more. Probably you want to ensure that single quotes > always come in even-numbered runs. > > Instead of looking for a single quote in the middle of that regular > expression, we'll look for a single quote followed by an even number > of single quotes. Then we'll add one more. > > irb(main):006:0> input3 = "'''Jimbo' said, 'this isn''t too hard'.''" > => "'''Jimbo' said, 'this isn''t too hard'.''" > irb(main):007:0> input3.gsub( /(\A|[^'])'('')*([^']|\Z)/, "\\1''\\2\ > \3" ) > => "''''Jimbo'' said, ''this isn''t too hard''.''" > > > (The above could be made a bit simpler with lookaheads and > lookbehinds. I've chosen not to use them because you need Oniguruma > to do lookbehinds, and no sense cluttering the example with one > technique for the front and another for the back.) > > I've been fighting to figure out how a regexp should look, so I appreciate very much your approach. I will be reading it carefully. thanks, ./alex -- .w( the_mindstorm )p.