On Jan 18, 2006, at 7:47 AM, Alexandru P. 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.)