# Gsub problem

**URL:** <https://www.ruby-forum.com/t/gsub-problem/182251>\
**Category:** Ruby\
**Created:** [January 25, 2010, 5:50pm UTC](https://www.ruby-forum.com/t/gsub-problem/182251 "2010-01-25T17:50:35Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![lalawawa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e480ec/32.png) [@lalawawa](https://www.ruby-forum.com/u/lalawawa)\
**Post date:** [January 25, 2010, 5:50pm UTC](https://www.ruby-forum.com/t/gsub-problem/182251/1 "2010-01-25T17:50:35Z")

</div>

I’m trying to use gsub to put escapes before single quotes.

irb(main):001:0\> a = “Ain’t Can’t”  
=\> “Ain’t Can’t”  
irb(main):002:0\> a.gsub(/(’)/, ‘\1’)  
=\> “Ain’t Can’t”  
irb(main):003:0\> a.gsub(/(’)/, ‘\\1’)  
=\> “Ain\1t Can\1t”  
irb(main):004:0\> a.gsub(/(’)/, ‘\\1’)  
=\> “Ain\1t Can\1t”  
irb(main):005:0\> a.gsub(/(’)/, ‘\\\1’)  
=\> “Ain\'t Can\'t”  
irb(main):006:0\>

How does one do it?

---

<div class="post-metadata">

**Author:** ![lalawawa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e480ec/32.png) [@lalawawa](https://www.ruby-forum.com/u/lalawawa)\
**Post date:** [January 25, 2010, 6:03pm UTC](https://www.ruby-forum.com/t/gsub-problem/182251/2 "2010-01-25T18:03:29Z")

</div>

Actually, I oversimplified my example. I want to escape single quotes  
and question marks.

irb(main):001:0\> a = “Can’t we?”  
=\> “Can’t we?”  
irb(main):002:0\> a.gsub(/([’?])/, ‘\1’)  
=\> “Can’t we?”  
irb(main):003:0\> a.gsub(/([’?])/, ‘\\1’)  
=\> “Can\1t we\1”  
irb(main):004:0\> a.gsub(/([’?])/, ‘\\1’)  
=\> “Can\1t we\1”  
irb(main):005:0\> a.gsub(/([’?])/, ‘\\\1’)  
=\> “Can\'t we\?”  
irb(main):006:0\>

---

<div class="post-metadata">

**Author:** ![lalawawa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e480ec/32.png) [@lalawawa](https://www.ruby-forum.com/u/lalawawa)\
**Post date:** [January 25, 2010, 6:30pm UTC](https://www.ruby-forum.com/t/gsub-problem/182251/3 "2010-01-25T18:30:26Z")

</div>

On 2010-01-25, lalawawa [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> irb(main):005:0\> a.gsub(/(['?])/, ‘\\\1’)  
> =\> “Can\'t we\?”

This is probably what you want – keep in mind that irb will show  
you escaped backslashes if there’s a single backslash in the string.

-s

---

<div class="post-metadata">

**Author:** ![lalawawa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e480ec/32.png) [@lalawawa](https://www.ruby-forum.com/u/lalawawa)\
**Post date:** [January 25, 2010, 6:52pm UTC](https://www.ruby-forum.com/t/gsub-problem/182251/4 "2010-01-25T18:52:41Z")

</div>

Seebs wrote:

> On 2010-01-25, lalawawa [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > irb(main):005:0\> a.gsub(/(['?])/, ‘\\\1’)  
> > =\> “Can\'t we\?”
> 
> This is probably what you want – keep in mind that irb will show  
> you escaped backslashes if there’s a single backslash in the string.
> 
> -s

You’re right.

irb(main):009:0\> puts a.gsub(/(['?])/, ‘\\\1’)  
Can't we?  
=\> nil  
irb(main):010:0\>

Thanks

---

<div class="post-metadata">

**Author:** ![lalawawa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e480ec/32.png) [@lalawawa](https://www.ruby-forum.com/u/lalawawa)\
**Post date:** [January 25, 2010, 7:03pm UTC](https://www.ruby-forum.com/t/gsub-problem/182251/5 "2010-01-25T19:03:13Z")

</div>

On Jan 25, 2010, at 12:50 PM, lalawawa wrote:

> irb(main):009:0\> puts a.gsub(/(['?])/, ‘\\\1’)  
> Can't we?  
> =\> nil  
> irb(main):010:0\>
> 
> Thanks

You can get rid of a few backslashes if you like:

$ irb --simple-prompt

> > a = “Can’t we?”  
> > =\> “Can’t we?”  
> > puts a.gsub(/['?]/) { |c| “\#{c}” }  
> > Can't we?  
> > =\> nil

Mike

–

Mike S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[http://www.stok.ca/~mike/](http://www.stok.ca/~mike/)

The “`Stok’ disclaimers” apply.

---

<div class="post-metadata">

**Author:** ![lalawawa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e480ec/32.png) [@lalawawa](https://www.ruby-forum.com/u/lalawawa)\
**Post date:** [January 25, 2010, 7:35pm UTC](https://www.ruby-forum.com/t/gsub-problem/182251/6 "2010-01-25T19:35:25Z")

</div>

On Jan 25, 2010, at 12:00 PM, lalawawa wrote:

> =\> “Can\1t we\1”  
> irb(main):005:0\> a.gsub(/(['?])/, ‘\\\1’)  
> =\> “Can\'t we\?”

(Well, Mike’s answer steals my thunder a bit, but I’ll put this out  
there for anyone else that finds this thread.)

You just have to remember that there’s two levels of confusion, uh, I  
mean _escaping_ going on here.

Within single-quoted strings, the only backslash-escape is for a ’  
and, so you can have a , you also need to escape the escape character:

‘\1’ means a backslash and a digit (because the character following  
the \ is not ’ or \ it doesn’t have its special meaning)  
‘\1’ means an escaped backslash and a digit (yes, the same as above,  
but this time the first \ escapes the second \ so that it is  
interpreted literally)  
‘\\1’ means an escaped backslash, a backslash, and a digit (you see  
where this is going, right?)

Now, within the replacement string for a gsub, you can have a  
backslash-digit to mean “the n-th parenthesized group where the digit  
is n”

So you want to replace with “a backslash and a backslash-digit for the  
first group”. You need the final interpretation of the replacement to  
end up as \ \1 (no quotes here to confuse things)

‘\’ is a literal   
‘\\’ is a literal \ so gsub will see a real   
‘\1’ is \1 because 1 isn’t a special character  
SO…  
‘\\\1’ is seen as \\1 (as the argument) and gsub interprets it as  
“literal backslash, first group”

‘\\\1’ is seen the same way; the fifth backslash escapes the sixth,  
then the 1

You might consider using the block form of gsub replacement.

irb\> a = “Can’t we?”  
=\> “Can’t we?”  
irb\> a.gsub(/([‘?])/, ‘\\\1’)  
=\> “Can\'t we\?”  
irb\> puts \_  
Can't we?  
=\> nil  
irb\> a.gsub(/[’?]/) {|m| ‘\’ + m}  
=\> “Can\'t we\?”  
irb\> puts \_  
Can't we?  
=\> nil

In your case, the clarity that results from the simplification of the  
replacement should be obvious.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![lalawawa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/e480ec/32.png) [@lalawawa](https://www.ruby-forum.com/u/lalawawa)\
**Post date:** [January 27, 2010, 2:05am UTC](https://www.ruby-forum.com/t/gsub-problem/182251/7 "2010-01-27T02:05:33Z")

</div>

Rob B. wrote:

> > =\> “Can\1t we\1”  
> > You just have to remember that there’s two levels of confusion, uh, I  
> > ‘\\1’ means an escaped backslash, a backslash, and a digit (you see  
> > ‘\’ is a literal \
> 
> Can't we?  
> =\> nil
> 
> In your case, the clarity that results from the simplification of the  
> replacement should be obvious.
> 
> -Rob
> 
> Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
> removed\_email\_address@domain.invalid

Most excellent and informative posts, Rob and Mike. I’ve saved them  
both to my “best of Ruby” folder.
