[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

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

Lloyd Zusman

3/17/2009 6:59:00 PM

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.



4 Answers

Lloyd Zusman

3/17/2009 7:52:00 PM

0

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.



matt

3/17/2009 8:14:00 PM

0

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

$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...! :) m.

--
matt neuburg, phd = matt@tidbits.com, http://www.tidbits...
Leopard - http://www.takecontrolbooks.com/leopard-custom...
AppleScript - http://www.amazon.com/gp/product/...
Read TidBITS! It's free and smart. http://www.t...

Ken Bloom

3/18/2009 1:42:00 AM

0

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.

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

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

Ken Bloom

3/18/2009 1:43:00 AM

0

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
> }

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.


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