Backreferences in case statements

Discussion in 'Ruby' started by loveajax@gmail.com, May 3, 2008.

  1. Guest

    Hi,

    I am not sure if this is possible. I have a case statement which
    checks for a regular expression. For example:

    case text
    when /(abc)(.)*/
    when /(xyz)(.)*/
    end

    In the above snippet how can I use the instance variables pre_match
    and post_match? I tried calling these methods without any qualifiers
    but I got a NoMethodError. Where does Ruby store the MatchData if the
    matching is done in a case statement?

    Thanks
    -subbu
     
    , May 3, 2008
    #1
    1. Advertising

  2. ara.t.howard Guest

    On May 3, 2008, at 10:05 AM, wrote:
    > In the above snippet how can I use the instance variables pre_match
    > and post_match? I tried calling these methods without any qualifiers
    > but I got a NoMethodError. Where does Ruby store the MatchData if the
    > matching is done in a case statement?



    $1, $2, etc.

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, May 3, 2008
    #2
    1. Advertising

  3. On 03.05.2008 18:00, wrote:

    > I am not sure if this is possible. I have a case statement which
    > checks for a regular expression. For example:
    >
    > case text
    > when /(abc)(.)*/
    > when /(xyz)(.)*/
    > end
    >
    > In the above snippet how can I use the instance variables pre_match
    > and post_match? I tried calling these methods without any qualifiers
    > but I got a NoMethodError. Where does Ruby store the MatchData if the
    > matching is done in a case statement?


    $ irb
    irb(main):001:0> /b/ =~ "abc"
    => 1
    irb(main):002:0> $`
    => "a"
    irb(main):003:0> $'
    => "c"
    irb(main):004:0> $~
    => #<MatchData:0x7ff9eb54>
    irb(main):005:0> $~.to_a
    => ["b"]
    irb(main):006:0> $~.pre_match
    => "a"
    irb(main):007:0> $~.post_match
    => "c"
    irb(main):008:0>

    But why do you have groups in your regular expressions if you are not
    interested in the content? Also "(.)*" seems a bit odd because it might
    not yield what you expect:

    irb(main):008:0> /a(.)*/ =~ "abcdef"
    => 0
    irb(main):009:0> $1
    => "f"

    IMHO it is generally a bad idea to use grouping in the way you do it
    because it will capture a lot that you are not interested in. It seems
    you might rather want "(.*)".

    Kind regards

    robert
     
    Robert Klemme, May 4, 2008
    #3
  4. Pit Capitain Guest

    2008/5/3 <>:
    > Where does Ruby store the MatchData if the
    > matching is done in a case statement?


    Subbu, there's also Regexp.last_match. Sometimes this reads better
    than those Perl-like variables.

    Regards,
    Pit
     
    Pit Capitain, May 4, 2008
    #4
  5. Guest

    On May 4, 3:11 am, Robert Klemme <> wrote:
    > On 03.05.2008 18:00, wrote:
    >
    > > I am not sure if this is possible. I have a case statement which
    > > checks for a regular expression. For example:

    >
    > > case text
    > > when /(abc)(.)*/
    > > when /(xyz)(.)*/
    > > end

    >
    > > In the above snippet how can I use the instance variables pre_match
    > > and post_match? I tried calling these methods without any qualifiers
    > > but I got a NoMethodError. Where does Ruby store the MatchData if the
    > > matching is done in a case statement?

    >
    > $ irb
    > irb(main):001:0> /b/ =~ "abc"
    > => 1
    > irb(main):002:0> $`
    > => "a"
    > irb(main):003:0> $'
    > => "c"
    > irb(main):004:0> $~
    > => #<MatchData:0x7ff9eb54>
    > irb(main):005:0> $~.to_a
    > => ["b"]
    > irb(main):006:0> $~.pre_match
    > => "a"
    > irb(main):007:0> $~.post_match
    > => "c"
    > irb(main):008:0>
    >
    > But why do you have groups in your regular expressions if you are not
    > interested in the content?  Also "(.)*" seems a bit odd because it might
    > not yield what you expect:
    >
    > irb(main):008:0> /a(.)*/ =~ "abcdef"
    > => 0
    > irb(main):009:0> $1
    > => "f"
    >
    > IMHO it is generally a bad idea to use grouping in the way you do it
    > because it will capture a lot that you are not interested in.  It seems
    > you might rather want "(.*)".
    >
    > Kind regards
    >
    >         robert


    Hey Robert,

    In my guess /b/ =~ "abc" is what sets $~ variable. Since I am not
    using that statement anywhere that variable is not set at all. Instead
    I am doing the matching in a case statement. As a result I am not able
    to do something like $~.pre_match. I am not fond of $1, $2, etc
    variables. I feel comfortable using the instance variables pre_match
    and post_match.

    But you solved the first problem I was trying to solve :) I was using
    (.)* instead of (.*) and I couldn't get what I wanted. (.*) is what I
    needed. Thanks so much for that. Now I can use $1, $2 at least if not
    pre_match and post_match.

    -subbu
     
    , May 4, 2008
    #5
  6. Guest

    On May 4, 5:40 am, Pit Capitain <> wrote:
    > 2008/5/3  <>:
    >
    > >  Where does Ruby store the MatchData if the
    > >  matching is done in a case statement?

    >
    > Subbu, there's also Regexp.last_match. Sometimes this reads better
    > than those Perl-like variables.
    >
    > Regards,
    > Pit


    Hi Pitt,

    I did use Regexp.last_match. But its a class method. I am interested
    in using something like pre_match and post_match methods which are
    instance variables. But looks like my code never created the instance
    of MatchData.

    Thanks
    -subbu
     
    , May 4, 2008
    #6
  7. James Gray Guest

    On May 4, 2008, at 8:25 AM, wrote:

    > On May 4, 5:40 am, Pit Capitain <> wrote:
    >> 2008/5/3 <>:
    >>
    >>> Where does Ruby store the MatchData if the
    >>> matching is done in a case statement?

    >>
    >> Subbu, there's also Regexp.last_match. Sometimes this reads better
    >> than those Perl-like variables.
    >>
    >> Regards,
    >> Pit

    >
    > Hi Pitt,
    >
    > I did use Regexp.last_match. But its a class method. I am interested
    > in using something like pre_match and post_match methods which are
    > instance variables. But looks like my code never created the instance
    > of MatchData.


    Regexp.last_match.pre_match

    James Edward Gray II
     
    James Gray, May 4, 2008
    #7
  8. On 04.05.2008 15:21, wrote:
    > On May 4, 3:11 am, Robert Klemme <> wrote:
    >> On 03.05.2008 18:00, wrote:
    >>
    >>> I am not sure if this is possible. I have a case statement which
    >>> checks for a regular expression. For example:
    >>> case text
    >>> when /(abc)(.)*/
    >>> when /(xyz)(.)*/
    >>> end
    >>> In the above snippet how can I use the instance variables pre_match
    >>> and post_match? I tried calling these methods without any qualifiers
    >>> but I got a NoMethodError. Where does Ruby store the MatchData if the
    >>> matching is done in a case statement?

    >> $ irb
    >> irb(main):001:0> /b/ =~ "abc"
    >> => 1
    >> irb(main):002:0> $`
    >> => "a"
    >> irb(main):003:0> $'
    >> => "c"
    >> irb(main):004:0> $~
    >> => #<MatchData:0x7ff9eb54>
    >> irb(main):005:0> $~.to_a
    >> => ["b"]
    >> irb(main):006:0> $~.pre_match
    >> => "a"
    >> irb(main):007:0> $~.post_match
    >> => "c"
    >> irb(main):008:0>
    >>
    >> But why do you have groups in your regular expressions if you are not
    >> interested in the content? Also "(.)*" seems a bit odd because it might
    >> not yield what you expect:
    >>
    >> irb(main):008:0> /a(.)*/ =~ "abcdef"
    >> => 0
    >> irb(main):009:0> $1
    >> => "f"
    >>
    >> IMHO it is generally a bad idea to use grouping in the way you do it
    >> because it will capture a lot that you are not interested in. It seems
    >> you might rather want "(.*)".


    > In my guess /b/ =~ "abc" is what sets $~ variable. Since I am not
    > using that statement anywhere that variable is not set at all.


    That's complete nonsense. Did you try it out? I guess not. Come on,
    don't be so lazy.

    > Instead
    > I am doing the matching in a case statement. As a result I am not able
    > to do something like $~.pre_match. I am not fond of $1, $2, etc
    > variables. I feel comfortable using the instance variables pre_match
    > and post_match.


    pre_match and post_match are not instance variables but methods of class
    MatchData.

    > But you solved the first problem I was trying to solve :) I was using
    > (.)* instead of (.*) and I couldn't get what I wanted. (.*) is what I
    > needed. Thanks so much for that. Now I can use $1, $2 at least if not
    > pre_match and post_match.


    irb(main):007:0> /b/ === "abc"
    => true
    irb(main):008:0> $~
    => #<MatchData:0x100230b8>
    irb(main):009:0> $~.pre_match
    => "a"
    irb(main):010:0> $~.post_match
    => "c"
    irb(main):011:0>

    robert
     
    Robert Klemme, May 4, 2008
    #8
  9. On Sun, May 4, 2008 at 11:22 AM, David A. Black <> wrote:

    > > > 2008/5/3 <>:
    > > > > Where does Ruby store the MatchData if the
    > > > > matching is done in a case statement?

    >
    > Matching doesn't change in or out of a case statement; it's still the
    > same thing.


    > Ruby keeps track of the last match operation performed, and that's
    > what you get in $~ (which is a MatchData object) and some of the
    > Regexp class methods.


    And $~ is actually a thread local global, so it holds the matchdata
    produced by the last successful match on the current thread.

    I'm pretty sure that Regexp.last_match is thread-safe as well.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, May 5, 2008
    #9
  10. Hi --

    On Mon, 5 May 2008, Rick DeNatale wrote:

    > On Sun, May 4, 2008 at 11:22 AM, David A. Black <> wrote:
    >
    >>>> 2008/5/3 <>:
    >>>>> Where does Ruby store the MatchData if the
    >>>>> matching is done in a case statement?

    >>
    >> Matching doesn't change in or out of a case statement; it's still the
    >> same thing.

    >
    >> Ruby keeps track of the last match operation performed, and that's
    >> what you get in $~ (which is a MatchData object) and some of the
    >> Regexp class methods.

    >
    > And $~ is actually a thread local global, so it holds the matchdata
    > produced by the last successful match on the current thread.
    >
    > I'm pretty sure that Regexp.last_match is thread-safe as well.


    I believe it just returns $~, so it should be identical in terms of
    thread safety.


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    INTRO TO RAILS June 9-12 Berlin
    ADVANCING WITH RAILS June 16-19 Berlin
    INTRO TO RAILS June 24-27 London (Skills Matter)
    See http://www.rubypal.com for details and updates!
     
    David A. Black, May 5, 2008
    #10
    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. Neil Zanella
    Replies:
    8
    Views:
    1,232
    mfmehdi
    Oct 20, 2006
  2. Mark Fletcher
    Replies:
    1
    Views:
    506
    Mark Fletcher
    May 19, 2004
  3. Harry George
    Replies:
    6
    Views:
    444
    Bart Nessux
    Feb 23, 2004
  4. Vince
    Replies:
    12
    Views:
    775
    Martin Gregorie
    Jan 21, 2008
  5. John Crichton
    Replies:
    6
    Views:
    289
    John Crichton
    Jul 12, 2010
Loading...

Share This Page