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

Discussion in 'Ruby' started by Lloyd Zusman, Mar 17, 2009.

  1. Lloyd Zusman

    Lloyd Zusman Guest

    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

    God bless you.
    Lloyd Zusman, Mar 17, 2009
    #1
    1. Advertising

  2. Lloyd Zusman

    Lloyd Zusman Guest

    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

    God bless you.
    Lloyd Zusman, Mar 17, 2009
    #2
    1. Advertising

  3. Lloyd Zusman

    matt neuburg Guest

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


    $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 = , http://www.tidbits.com/matt/
    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
    matt neuburg, Mar 17, 2009
    #3
  4. Lloyd Zusman

    Ken Bloom Guest

    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/~kbloom1/
    Ken Bloom, Mar 18, 2009
    #4
  5. Lloyd Zusman

    Ken Bloom Guest

    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/~kbloom1/
    Ken Bloom, Mar 18, 2009
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jitasi
    Replies:
    1
    Views:
    748
    Terry Reedy
    Mar 4, 2007
  2. Kevin Walzer

    Re: PIL (etc etc etc) on OS X

    Kevin Walzer, Aug 1, 2008, in forum: Python
    Replies:
    4
    Views:
    390
    Fredrik Lundh
    Aug 13, 2008
  3. John Elrick
    Replies:
    9
    Views:
    108
    John Carter
    Apr 7, 2005
  4. aurelianito

    gsub and gsub! are inconsistent

    aurelianito, Nov 8, 2005, in forum: Ruby
    Replies:
    9
    Views:
    162
    Robert Klemme
    Nov 9, 2005
  5. Abe
    Replies:
    2
    Views:
    168
Loading...

Share This Page