# How to double single quote (beginner blockage)

**URL:** <https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532>\
**Category:** Ruby\
**Created:** [January 18, 2006, 4:26pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532 "2006-01-18T16:26:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 4:26pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/1 "2006-01-18T16:26:24Z")

</div>

Hi!

Sorry for this `stupid´ question but it looks like i am suffering a  
mental blockage:

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

my `brainless´ attempt was:

```auto
fixed_value = ""
wrong_value.each_with_index do |char, idx|
	fixed_value << char
        	if ( (idx < wrong_value.size - 1) && (wrong_value[idx + 1] != 
'\'') && (idx > 0) &&
(wrong_value[idx - 1] != '\''))
                	fixed_value << '\''
        	end
end
```

but the above results in exactly the same strings. I would appreciate  
very much your help

./alex

---

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 4:41pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/2 "2006-01-18T16:41:44Z")

</div>

And what if the input string correctly contains double quotes?? 😉

String doesn’t have a each\_with\_index method.

class String  
def each\_with\_index  
counter = 0  
each\_byte do |char|  
yield char, counter  
counter += 1  
end  
end  
end

“abc”.each\_with\_index do |char, index|  
puts char.chr + ’ ’ + index.to\_s  
end

Please note that char is an integer, so you have to call char.chr.

Untested, but it should work.

---

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 5:05pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/3 "2006-01-18T17:05:42Z")

</div>

#: Jules J. changed the world a bit at a time by saying (astral  
date: 1/18/2006 5:05 PM) :#

> ```
> end
> 
> ```

I have passed over my no-brainer moment:

```auto
fixed_value = ""
idx = 0
while (idx < wrong_value.size) do
	fixed_value << wrong_value[idx]
	if ( wrong_value[idx] == 39 )
		if ( (wrong_value[idx + 1] != 39) )
			if ( idx > 0 && wrong_value[idx - 1] != 39 )
				fixed_value << '\''
			end
		end
         end
         idx += 1
end
```

but now i’ve reached the no-ruby point. Can you teach me what would be  
the ruby way?

Note: the double quotes are not considered in this problem; in fact i am  
removing them right from  
the beginning

./alex

---

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 5:05pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/4 "2006-01-18T17:05:42Z")

</div>

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.)

---

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 5:27pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/5 "2006-01-18T17:27:00Z")

</div>

On Thu, 19 Jan 2006, Gavin K. wrote:

> a single quote that has characters other than a single quote on either side,  
> =\> “‘Hey, it’s al’alamein’”  
> even-numbered runs.
> 
> (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.)

nice explanation gavin. my brain is too feeble for that but i do the  
same  
thing logically using

irb(main):016:0\> %Q( ‘’‘Jimbo’ said, ‘this isn’‘t too hard’.’’  
).gsub(/’+/){|m| m.size % 2 == 0 ? m : m \<\< “’”}  
=\> " ‘’’‘Jimbo’’ said, ‘‘this isn’‘t too hard’’.’’ "

i assume it would be slower though.

cheers.

-a

---

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 5:33pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/6 "2006-01-18T17:33:11Z")

</div>

#: Gavin K. changed the world a bit at a time by saying (astral  
date: 1/18/2006 5:28 PM) :#

> to find a single quote that has characters other than a single quote  
> =\> “‘Hey, it’s al’alamein’”  
> always come in even-numbered runs.
> 
> (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

---

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 5:33pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/7 "2006-01-18T17:33:12Z")

</div>

#: Gavin K. changed the world a bit at a time by saying (astral  
date: 1/18/2006 5:28 PM) :#

> to find a single quote that has characters other than a single quote  
> =\> “‘Hey, it’s al’alamein’”  
> always come in even-numbered runs.
> 
> (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 (mainly the  
first/last position part), so  
I appreciate very much your approach. I will be reading it carefully.

… and what is Oniguruma? (sounds pretty cool 🙂 ).

thanks,

./alex

---

<div class="post-metadata">

**Author:** ![Alexandru\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@Alexandru\_P](https://www.ruby-forum.com/u/Alexandru_P)\
**Post date:** [January 18, 2006, 6:39pm UTC](https://www.ruby-forum.com/t/how-to-double-single-quote-beginner-blockage/102532/8 "2006-01-18T18:39:24Z")

</div>

The new Regex library for Ruby 2.0?

Jules
