Forum: Ruby simple question about Ruby Regext

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 14:57
Hi,
I've been learning RUBY the past 7 months or so, and, now, my assistant
is doing the same. In her perusal of the "Programming RUBY" book, first
edition, she's come across a simple, simple regex truism that throws
her, and throws me, too!

Why is this true?

"banana" =~ /an*/
=>1

This is driving me nuts. Why isn't the RUBY response "=>2?" There are
two "an" stubs in "banana."

I thought that RUBY, like PERL, is inherently greedy and it would find
all instances of said regex expression.

Thanks a lot!
Peter
Ad7805c9fcc1f13efc6ed11251a6c4d2?d=identicon&s=25 Alex Young (regularfry)
on 2007-01-26 15:01
(Received via mailing list)
Peter Bailey wrote:
>
> This is driving me nuts. Why isn't the RUBY response "=>2?" There are
> two "an" stubs in "banana."
The number returned is the position of the start of match, not the
number of them.

> I thought that RUBY, like PERL, is inherently greedy and it would find
> all instances of said regex expression.
It is...  there's only one match, and it matches everything from the
first 'a' to the end of the string.

Hope this makes sense,
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-01-26 15:10
(Received via mailing list)
On Jan 26, 2007, at 7:57 AM, Peter Bailey wrote:

> I thought that RUBY, like PERL, is inherently greedy and it would find
> all instances of said regex expression.

I see you already have your answer, so I will just add that those
languages are spelled Ruby and Perl.  Welcome to Ruby!

James Edward Gray II
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 15:24
Alex Young wrote:
> Peter Bailey wrote:
>>
>> This is driving me nuts. Why isn't the RUBY response "=>2?" There are
>> two "an" stubs in "banana."
> The number returned is the position of the start of match, not the
> number of them.
>
>> I thought that RUBY, like PERL, is inherently greedy and it would find
>> all instances of said regex expression.
> It is...  there's only one match, and it matches everything from the
> first 'a' to the end of the string.
>
> Hope this makes sense,

Thanks, Gentlemen. I'll watch my spelling of Ruby and Perl from now on.

I understand now that my match is only looking for the position. Cool.
Thanks. But, . . ., here's a similar regex where I don't want the
position, but I want to change all instances of the stub, and, it's only
changing the first one.

"banana".sub(/an/, "ze")
=> "bzeana"

What's with that?

-Peter
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-01-26 15:30
(Received via mailing list)
On 26.01.2007 15:24, Peter Bailey wrote:
>> first 'a' to the end of the string.
> "banana".sub(/an/, "ze")
> => "bzeana"
>
> What's with that?

ri String#sub
ri String#gsub

And, for completeness reasons

ri String#sub!
ri String#gsub!

Kind regards

  robert
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-01-26 15:31
(Received via mailing list)
On 26.01.2007 15:00, Alex Young wrote:
>> =>1
>>
>> This is driving me nuts. Why isn't the RUBY response "=>2?" There are
>> two "an" stubs in "banana."
> The number returned is the position of the start of match, not the
> number of them.
>
>> I thought that RUBY, like PERL, is inherently greedy and it would find
>> all instances of said regex expression.
> It is...  there's only one match, and it matches everything from the
> first 'a' to the end of the string.

No.  It's just matching "an":

irb(main):001:0> "banana"[/an*/]
=> "an"

You were right if the regexp had a dot:

irb(main):002:0> "banana"[/an.*/]
=> "anana"

  robert
Ad7805c9fcc1f13efc6ed11251a6c4d2?d=identicon&s=25 Alex Young (regularfry)
on 2007-01-26 15:32
(Received via mailing list)
Peter Bailey wrote:
>> first 'a' to the end of the string.
> "banana".sub(/an/, "ze")
> => "bzeana"
That's explicitly what sub is for - only changing the first one.  You
want gsub.
9a644ee8f45272d562ad8679886e75c0?d=identicon&s=25 jeff gr (jgrice)
on 2007-01-26 15:33
(Received via mailing list)
try "banana".gsub(/an/, "ze")
=> "bzezea"
Ad7805c9fcc1f13efc6ed11251a6c4d2?d=identicon&s=25 Alex Young (regularfry)
on 2007-01-26 15:35
(Received via mailing list)
Robert Klemme wrote:
>>> "banana" =~ /an*/
>> first 'a' to the end of the string.
>
Oops :-)  Sorry for any confusion.  Not enough blood in my caffeine
system, obviously :-)
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 15:36
Alex Young wrote:
> Peter Bailey wrote:
>>> first 'a' to the end of the string.
>> "banana".sub(/an/, "ze")
>> => "bzeana"
> That's explicitly what sub is for - only changing the first one.  You
> want gsub.

Got it. Thanks, guys. Yes, I should've used gsub, of course. So, I'm not
going nuts.
A131b672fdbd2a58dce12031ad78b121?d=identicon&s=25 Wolfgang Nádasi-Donner (wonado)
on 2007-01-26 15:36
(Received via mailing list)
Peter Bailey schrieb:
> Why is this true?
>
> "banana" =~ /an*/
> =>1
As already said, it is the position of the match.

> I thought that RUBY, like PERL, is inherently greedy and it would find
> all instances of said regex expression.

If you want to find all matches, you should use "scan" in Ruby. There
are two
possibilities. the first one...

   str = 'banana'
   str.scan(/an/) # => ["an", "an"]

...will produce an Array object for each match (see "ri String#scan" for
details). The second one will invoke a block for each match.

   str = 'banana'
   str.scan(/an/) do
     puts "#$`<#$&>#$'"
   end

produces:

   b<an>ana
   ban<an>a

Wolfgang Nádasi-Donner
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 15:45
Thanks, Wolfgang. So, you suggest the use of "scan" instead of "gsub?"
That would imply the need for a block, which, seems kind of wordy, but,
it does have power. . . . Thanks again.
05e4e83c87a5700958fcb3efa8951a06?d=identicon&s=25 vasudevram (Guest)
on 2007-01-26 15:50
(Received via mailing list)
On Jan 26, 7:33 pm, Wolfgang Nádasi-Donner <won...@donnerweb.de>
wrote:

 The second one will invoke a block for each match.
>
> Wolfgang Nádasi-Donner

Hey, that's both a neat Ruby feature and a neat way to explain it :-)
Thanks
Vasudev Ram
http://www.dancingbison.com
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 15:53
vasudevram wrote:
> On Jan 26, 7:33 pm, Wolfgang N�dasi-Donner <won...@donnerweb.de>
> wrote:
>
>  The second one will invoke a block for each match.
>>
>> Wolfgang N�dasi-Donner
>
> Hey, that's both a neat Ruby feature and a neat way to explain it :-)
> Thanks
> Vasudev Ram
> http://www.dancingbison.com

This is indeed the most generous of forums. I would've been flamed long
ago in the Perl world.
D1588981e0248aaa0174906c99df180e?d=identicon&s=25 Andy Lester (Guest)
on 2007-01-26 16:10
(Received via mailing list)
> This is indeed the most generous of forums. I would've been flamed
> long
> ago in the Perl world.

I suggest that it's not a feature of Perl per se, but of the larger
number of people in Perl.  Given a large enough group, you'll always
have a percentage of people who are jerks.  I've already run into
people who've treated me poorly because I was new and unfamiliar to
them.

xoxo,
Andy
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-01-26 16:15
(Received via mailing list)
On 26.01.2007 15:53, Peter Bailey wrote:
> This is indeed the most generous of forums. I would've been flamed long
> ago in the Perl world.

Actually we are so kind that we will even arrange for flaming if you
miss it.[1]  Just place a hint in your postings. :-)))

Kind regards

  robert


[1] Though I cannot guarantee that it will be a really bad flame -
people around here might be a bit out of practice. ;-)
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-01-26 16:18
(Received via mailing list)
On Sat, 27 Jan 2007, Andy Lester wrote:

>> This is indeed the most generous of forums. I would've been flamed long
>> ago in the Perl world.
>
> I suggest that it's not a feature of Perl per se, but of the larger number
> of people in Perl.  Given a large enough group, you'll always have a
> percentage of people who are jerks.  I've already run into people who've
> treated me poorly because I was new and unfamiliar to them.

in fairness to perl i'd say this is probably true.  on the otherhand i
expect
that the ruby community will continue to be kind as a result of the
current
community sense of politeness and our desire for a comfortable place to
get
ruby help fast and with no bitter after taste.  in summary i think it's
up to
us to make sure this community doesn't follow the path of many large
communities: we don't have to accept that large means rude and
anonymous.

kind regards.

-a
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 16:24

Yeh, I didn't mean to denegrate Perl in any way. I worked with it just
fine for a few years. It probably does just have to do with the size of
the community, but, most of all, with my own greenness. So, kudos to all
jeweled programming languages. ( -:

-Peter
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-01-26 16:50
(Received via mailing list)
On Jan 26, 2007, at 8:45 AM, Peter Bailey wrote:

>
> Thanks, Wolfgang. So, you suggest the use of "scan" instead of "gsub?"
> That would imply the need for a block, which, seems kind of wordy,
> but,
> it does have power. . . . Thanks again.

gsub/gsub! also take a block.

Which one you use depends mainly on your purpose.  Here's how I view
the methods, in terms of a "Find and Replace" feature set common to
so many programs:

sub/sub!   == Find
gsub/gsub! == Find and Replace
scan       == Find All

Hope that helps.

James Edward Gray II
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 17:44
James Gray wrote:
> On Jan 26, 2007, at 8:45 AM, Peter Bailey wrote:
>
>>
>> Thanks, Wolfgang. So, you suggest the use of "scan" instead of "gsub?"
>> That would imply the need for a block, which, seems kind of wordy,
>> but,
>> it does have power. . . . Thanks again.
>
> gsub/gsub! also take a block.
>
> Which one you use depends mainly on your purpose.  Here's how I view
> the methods, in terms of a "Find and Replace" feature set common to
> so many programs:
>
> sub/sub!   == Find
> gsub/gsub! == Find and Replace
> scan       == Find All
>
> Hope that helps.
>
> James Edward Gray II

That does help, James. Thanks. But, don't "sub" and "sub!" do a
replacement; so, they're doing more than just finding? At least, they're
finding and replacing the first instance of whatever, just not globally?
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-01-26 17:50
(Received via mailing list)
On Jan 26, 2007, at 10:44 AM, Peter Bailey wrote:

>> gsub/gsub! also take a block.
>>
>> James Edward Gray II
>
> That does help, James. Thanks. But, don't "sub" and "sub!" do a
> replacement; so, they're doing more than just finding? At least,
> they're
> finding and replacing the first instance of whatever, just not
> globally?

Ick.  Sorry.  In my defense I only got four hours of sleep last night.

Let me try my chart one more time:

sub/sub!   == Find and Replace
gsub/gsub! == Replace All
scan       == Find All

James Edward Gray II
B58c6eef325656d513d26e2c3ae6bfd9?d=identicon&s=25 Peter Bailey (peterbailey)
on 2007-01-26 17:57
>
> sub/sub!   == Find and Replace
> gsub/gsub! == Replace All
> scan       == Find All
>
> James Edward Gray II

Thanks! That's a good chart to keep in my head.
This topic is locked and can not be replied to.