From: Alex LeDonne Date: 2007-05-31T00:28:17+09:00 Subject: Re: Substituting Variables On 5/30/07, Andrew Stewart wrote: > 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. 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