# Substituting Variables

**URL:** <https://www.ruby-forum.com/t/substituting-variables/105515>\
**Category:** Ruby\
**Created:** [May 30, 2007, 5:10pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515 "2007-05-30T17:10:24Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 30, 2007, 5:10pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515/1 "2007-05-30T17:10:24Z")

</div>

Hello,

I am running into difficulties trying to use a variable in a  
substitution. Here’s an example:

var = ‘October’  
‘30 May 2007’.sub( /(\d+)\s(\w+)\s(\d+)/, ‘\1 #{var} \3’ )

Here I would like to get ‘30 October 2007’. The back-references,  
i.e. \1 and \3, only work within single quotation marks. But the  
interpolation only works within double quotation marks. What to do?

Here’s an example in IRB:

> > var = ‘October’  
> > re = /(\d+)\s(\w+)\s(\d+)/

> > ‘30 May 2007’.sub(re, ‘\1 #{var} \3’)  
> > =\> “30 #{var} 2007”

> > ‘30 May 2007’.sub(re, “\1 #{var} \3”)  
> > =\> “\001 October \003”

> > ‘30 May 2007’.sub(re, “#{$1} #{var} #{$3}”)  
> > =\> “30 October 2007”

Actually that last one does what I want – but according to the  
Pickaxe[1] $1 and friends aren’t supposed to work and in fact it  
doesn’t work in my Ruby class. So I think IRB is flattering to deceive.

[1] String.gsub: “If a string is used as the replacement, special  
variables from the match (such as $& and $1) cannot be substituted  
into it, as substitution into the string occurs before the pattern  
match starts. However, the sequences \1, \2, and so on may be used  
to interpolated successive groups in the match.”

I have found a workaround but I’m hoping there’s a better way:

> > ‘30 May 2007’.sub(re, ‘\1’ + " #{var} " + ‘\3’)  
> > =\> “30 October 2007”

Any insight would be much appreciated.

Thanks and regards,  
Andy S.

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 30, 2007, 5:15pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515/2 "2007-05-30T17:15:25Z")

</div>

Hi –

On Thu, 31 May 2007, Andrew S. wrote:

> works within double quotation marks. What to do?  
> Try:

“\1 #{var} \3”

David

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 30, 2007, 5:17pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515/3 "2007-05-30T17:17:25Z")

</div>

On 5/30/07, Andrew S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I am running into difficulties trying to use a variable in a  
> substitution. Here’s an example:
> 
> var = ‘October’  
> ‘30 May 2007’.sub( /(\d+)\s(\w+)\s(\d+)/, ‘\1 #{var} \3’ )
> 
> Here I would like to get ‘30 October 2007’. The back-references,  
> i.e. \1 and \3, only work within single quotation marks. But the  
> interpolation only works within double quotation marks. What to do?

Use double slashes.

irb(main):001:0\> var = ‘October’  
irb(main):002:0\> ‘30 May 2007’.sub( /(\d+)\s(\w+)\s(\d+)/, “\1 #{var}  
\3” )  
=\> “30 October 2007”

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 30, 2007, 5:18pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515/4 "2007-05-30T17:18:25Z")

</div>

Hello Andrew,

Use double quotes and escape slashes.  
‘30 May 2007’.sub( /(\d+)\s(\w+)\s(\d+)/, “\1 #{var} \3” )

Wednesday, May 30, 2007, 8:09:29 PM, you wrote:

AS\> Hello,

AS\> I am running into difficulties trying to use a variable in a  
AS\> substitution. Here’s an example:

AS\> var = ‘October’  
AS\> ‘30 May 2007’.sub( /(\d+)\s(\w+)\s(\d+)/, ‘\1 #{var} \3’ )

AS\> Here I would like to get ‘30 October 2007’. The back-references,  
AS\> i.e. \1 and \3, only work within single quotation marks. But the  
AS\> interpolation only works within double quotation marks. What to do?

AS\> Here’s an example in IRB:

> > > var = ‘October’  
> > > re = /(\d+)\s(\w+)\s(\d+)/

> > > ‘30 May 2007’.sub(re, ‘\1 #{var} \3’)  
> > > =\>\> “30 #{var} 2007”

> > > ‘30 May 2007’.sub(re, “\1 #{var} \3”)  
> > > =\>\> “\001 October \003”

> > > ‘30 May 2007’.sub(re, “#{$1} #{var} #{$3}”)  
> > > =\>\> “30 October 2007”

AS\> Actually that last one does what I want – but according to the  
AS\> Pickaxe[1] $1 and friends aren’t supposed to work and in fact it  
AS\> doesn’t work in my Ruby class. So I think IRB is flattering to  
deceive.

AS\> [1] String.gsub: “If a string is used as the replacement, special  
AS\> variables from the match (such as $& and $1) cannot be substituted  
AS\> into it, as substitution into the string occurs before the pattern  
AS\> match starts. However, the sequences \1, \2, and so on may be used  
AS\> to interpolated successive groups in the match.”

AS\> I have found a workaround but I’m hoping there’s a better way:

> > > ‘30 May 2007’.sub(re, ‘\1’ + " #{var} " + ‘\3’)  
> > > =\>\> “30 October 2007”

AS\> Any insight would be much appreciated.

AS\> Thanks and regards,  
AS\> Andy S.

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 30, 2007, 5:32pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515/5 "2007-05-30T17:32:27Z")

</div>

Hi David, Luis and Kane,

> Try:
> 
> “\1 #{var} \3”

That works swimmingly. Such fast replies too. Thank you very much!

Regards,  
Andy S.

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 30, 2007, 5:29pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515/6 "2007-05-30T17:29:26Z")

</div>

On 5/30/07, Andrew S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> interpolation only works within double quotation marks. What to do?  
> =\> “\001 October \003”  
> into it, as substitution into the string occurs before the pattern  
> Thanks and regards,  
> Andy S.

Same workaround, but easier to read (to me, anyway):  
‘30 May 2007’.sub(re, ‘\1 ’ \<\< var \<\< ’ \3’)  
Since you’re assembling a string, there’s no need to interpolate.

And, if you’re not using the middle capture group, do away with it. I  
also captured the spaces in the flanking groups.

re2 = /(\d+\s)\w+(\s\d+)/  
‘30 May 2007’.sub(re2, ‘\1’ \<\< var \<\< ‘\2’)

In 1.9, Oniguruma will give us zero-width lookahead and lookbehind.

-A

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 31, 2007, 12:27am UTC](https://www.ruby-forum.com/t/substituting-variables/105515/7 "2007-05-31T00:27:46Z")

</div>

On 5/30/07, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On 30.05.2007 17:28, Alex LeDonne wrote:
> 
> > Same workaround, but easier to read (to me, anyway):  
> > ‘30 May 2007’.sub(re, ‘\1 ’ \<\< var \<\< ’ \3’)  
> > Since you’re assembling a string, there’s no need to interpolate.
> 
> Um, what? Assembling strings is exactly what string interpolation is  
> used for (what else would it be?). Granted, there are multiple ways to  
> do it but your statement seems to be a bit off the mark.

Sorry for my imprecision, and thank you. I meant to say that if you’re  
_concatenating_, then there’s no need to interpolate. The  
double-quote, double-backslash solution presented by others uses  
interpolation instead of concatenation.

In hindsight, I suppose the backslash construction is also a form of  
interpolation, so my comment didn’t make much sense after all. Ah,  
well. At least the modified regex worked. 🙂

-Alex

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [May 30, 2007, 5:41pm UTC](https://www.ruby-forum.com/t/substituting-variables/105515/8 "2007-05-30T17:41:49Z")

</div>

On 30.05.2007 17:28, Alex LeDonne wrote:

> > i.e. \1 and \3, only work within single quotation marks. But the
> > 
> > > > ‘30 May 2007’.sub(re, “\1 #{var} \3”)  
> > > > variables from the match (such as $& and $1) cannot be substituted
> > 
> > Thanks and regards,  
> > Andy S.
> 
> Same workaround, but easier to read (to me, anyway):  
> ‘30 May 2007’.sub(re, ‘\1 ’ \<\< var \<\< ’ \3’)  
> Since you’re assembling a string, there’s no need to interpolate.

Um, what? Assembling strings is exactly what string interpolation is  
used for (what else would it be?). Granted, there are multiple ways to  
do it but your statement seems to be a bit off the mark.

> And, if you’re not using the middle capture group, do away with it. I  
> also captured the spaces in the flanking groups.
> 
> re2 = /(\d+\s)\w+(\s\d+)/  
> ‘30 May 2007’.sub(re2, ‘\1’ \<\< var \<\< ‘\2’)

Good point.

Kind regards

robert
