Interpolating $1, etc., from within a gsub block

I'm trying to use the block form of gsub in order to do substitution
involving an interpolation stored within a variable, but I can't
figure out how to get it to work. Here's a simplified case of what
I'm trying to do:

$fromre = Regexp.compile(ARGV[0])
$repl = ARGV[1]
$replcount = 0

string = "... something arbitrary ..."

string.gsub!($fromre) {
  >x>
  $replcount += 1
  $repl
}

As you can see, the regexp comes in on the command line, as well as
the replacement. I want to do this substution using the block form so
I can count the number of replacements that were made.

This works as long as $repl doesn't contain any references to matched
patterns. However, if this program is called 'myprog' and I do the
following, the replacement of $1 with the indicated subexpression
doesn't occur:

myprog 'abc(\S+)def' 'NEW-$1-MATCH'

In other words, if the string being substituted is this, "abcFOOBARdef",
the result is not "NEW-FOOBAR-MATCH" as I would like it to be, but rather,
"NEW-$1-MATCH".

It's clear why this doesn't work, but I can't figure out what construct
to use within the gsub block or on the command line to make sure that it
_does_ work.

I also tried this, and not surprisingly, it didn't work, either:

myprog 'abc(\S+)def' 'NEW-#{$1}-MATCH'

Can anyone suggest how I can accomplish this?

Thanks in advance.

···

--
Lloyd Zusman
ljz@asfast.com
God bless you.

Lloyd Zusman <ljz <at> asfast.com> writes:

[ ... ]

string.gsub!($fromre) {
  >x>
  $replcount += 1
  $repl
}

Well, I came up with the following, but I'm still wondering if there
is a more elegant way to do this:

string.gsub!($fromre) {
  >x>
  $replcount += 1
  eval "$result = \"#{$to}\""
  $result
}

Then, I have to invoke my program as follows:

myprog 'abc(\S+)def' 'NEW-#{$1}-MATCH'

Is this the best I can do, or is there something more elegant?

Thanks.

···

--
Lloyd Zusman
ljz@asfast.com
God bless you.

$fromre = /abc(\S+)def/
$repl = '"NEW-#{$1}-MATCH"'
string = "abcFOOBARdef"

string.gsub!($fromre) { |x|
  instance_eval($repl)
}

I don't like it any better than you do...! :slight_smile: m.

···

Lloyd Zusman <ljz@asfast.com> wrote:

I'm trying to use the block form of gsub in order to do substitution
involving an interpolation stored within a variable, but I can't
figure out how to get it to work. Here's a simplified case of what
I'm trying to do:

$fromre = Regexp.compile(ARGV[0])
$repl = ARGV[1]
$replcount = 0

string = "... something arbitrary ..."

string.gsub!($fromre) {
  >x>
  $replcount += 1
  $repl
}

As you can see, the regexp comes in on the command line, as well as
the replacement. I want to do this substution using the block form so
I can count the number of replacements that were made.

This works as long as $repl doesn't contain any references to matched
patterns. However, if this program is called 'myprog' and I do the
following, the replacement of $1 with the indicated subexpression
doesn't occur:

myprog 'abc(\S+)def' 'NEW-$1-MATCH'

In other words, if the string being substituted is this, "abcFOOBARdef",
the result is not "NEW-FOOBAR-MATCH" as I would like it to be, but rather,
"NEW-$1-MATCH".

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Leopard - http://www.takecontrolbooks.com/leopard-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

Variable interpolation only works for string literals inside ruby code.
If you bring in the string from anywhere else, you'll can use eval

eval '"'+string+'"' and hope there are no injection attacks in the string.

Alternatively, you can roll your own substitution:

string.gsub!($fromre) do |match|
  matchdata=Regexp.last_match
  $repl.gsub(/\$\d+/) do |subst|
     matchdata[subst[1..-1].to_i]
  end
end

--Ken

···

On Tue, 17 Mar 2009 13:59:24 -0500, Lloyd Zusman wrote:

I'm trying to use the block form of gsub in order to do substitution
involving an interpolation stored within a variable, but I can't figure
out how to get it to work. Here's a simplified case of what I'm trying
to do:

$fromre = Regexp.compile(ARGV[0])
$repl = ARGV[1]
$replcount = 0

string = "... something arbitrary ..."

string.gsub!($fromre) {
  >x>
  $replcount += 1
  $repl
}

As you can see, the regexp comes in on the command line, as well as the
replacement. I want to do this substution using the block form so I can
count the number of replacements that were made.

This works as long as $repl doesn't contain any references to matched
patterns. However, if this program is called 'myprog' and I do the
following, the replacement of $1 with the indicated subexpression
doesn't occur:

myprog 'abc(\S+)def' 'NEW-$1-MATCH'

In other words, if the string being substituted is this, "abcFOOBARdef",
the result is not "NEW-FOOBAR-MATCH" as I would like it to be, but
rather, "NEW-$1-MATCH".

It's clear why this doesn't work, but I can't figure out what construct
to use within the gsub block or on the command line to make sure that it
_does_ work.

I also tried this, and not surprisingly, it didn't work, either:

myprog 'abc(\S+)def' 'NEW-#{$1}-MATCH'

Can anyone suggest how I can accomplish this?

Thanks in advance.

--
Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

I think you're going overboard with variables (and global variables in
particular)

an eval "\"#{$to}\"" would have been sufficient here, and if you really
needed a new variable, then calling it simply result (without the dollar
sign) would have given you a local variable.

···

On Tue, 17 Mar 2009 14:52:08 -0500, Lloyd Zusman wrote:

Lloyd Zusman <ljz <at> asfast.com> writes:

[ ... ]

string.gsub!($fromre) {
  >x>
  $replcount += 1
  $repl
}

Well, I came up with the following, but I'm still wondering if there is
a more elegant way to do this:

string.gsub!($fromre) {
  >x>
  $replcount += 1
  eval "$result = \"#{$to}\""
  $result
}

--
Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/