Substituting Variables

A

Andrew Stewart

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:
=> "30 \#{var} 2007"
=> "\001 October \003"
=> "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 October 2007"

Any insight would be much appreciated.

Thanks and regards,
Andy Stewart
 
D

dblack

Hi --

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?

Try:

"\\1 #{var} \\3"


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
L

Luis Parravicini

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"
 
K

kane.sub

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:
=>> "30 \#{var} 2007"
=>> "\001 October \003"
=>> "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 October 2007"

AS> Any insight would be much appreciated.

AS> Thanks and regards,
AS> Andy Stewart
 
A

Alex LeDonne

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:
=> "30 \#{var} 2007"
=> "\001 October \003"
=> "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 October 2007"

Any insight would be much appreciated.

Thanks and regards,
Andy Stewart

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
 
R

Robert Klemme

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 Stewart

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
 
A

Alex LeDonne

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,139
Latest member
JamaalCald
Top