Backreferences in case statements

L

loveajax

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
 
A

ara.t.howard

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/
 
R

Robert Klemme

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
 
P

Pit Capitain

2008/5/3 said:
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
 
L

loveajax

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
 
L

loveajax

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
 
J

James Gray

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
 
R

Robert Klemme

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
 
R

Rick DeNatale

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

David A. Black

Hi --

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!
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top