Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   [Newbie] Stupid problem need simple answer (Array & RegExp) (http://www.velocityreviews.com/forums/t887027-newbie-stupid-problem-need-simple-answer-array-and-regexp.html)

Daedalus 06-24-2004 07:34 AM

[Newbie] Stupid problem need simple answer (Array & RegExp)
 
Keep in mind that I'm fresh one week years-old Perl newbie... thanks
I just need some information about what happen when :

my @string_list; #lets say that this array contain a couple of string, 3:
(the street, a book, theater)

foreach my $string (@string_list){
if ($string =~ s/(^the\b)|(^a\b)|//i){
$string_list[++$#string_lis] = $string
}
}

When I write: if ($string =~ s/(^the\b)|(^a\b)|//i)..., do I actually
replacing the string within @string_list (since $string is passed by
"foreach" from one of the string of @string_list) I'm asking cause I thought
that it would add the new strings to the array without touching what was
already there. So I would end with this list as @string_list (the street, a
book, theater, street, book).
But when try this, it overwrite and add. So it gives me ( street, book,
theater, street, book).
What am I doing wrong?

Thanks
DAE



Daedalus 06-24-2004 07:47 AM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
Well I think I was guessing right cause if I write this instead:

foreach (@string_list){
my $string = $_;
if ($string =~ s/(^the\b)|(^a\b)//i){
$string_list[++$#string_lis] = $string
}
}
I get the wanted result, but I would like someone to confirm that.

thanks
DAE


"Daedalus" <daedalus@videotron.ca> a écrit dans le message de news:
BsvCc.530$uY3.534@wagner.videotron.net...
> Keep in mind that I'm fresh one week years-old Perl newbie... thanks
> I just need some information about what happen when :
>
> my @string_list; #lets say that this array contain a couple of string,

3:
> (the street, a book, theater)
>
> foreach my $string (@string_list){
> if ($string =~ s/(^the\b)|(^a\b)//i){
> $string_list[++$#string_lis] = $string
> }
> }
>
> When I write: if ($string =~ s/(^the\b)|(^a\b)|//i)..., do I actually
> replacing the string within @string_list (since $string is passed by
> "foreach" from one of the string of @string_list) I'm asking cause I

thought
> that it would add the new strings to the array without touching what was
> already there. So I would end with this list as @string_list (the street,

a
> book, theater, street, book).
> But when try this, it overwrite and add. So it gives me ( street, book,
> theater, street, book).
> What am I doing wrong?
>
> Thanks
> DAE
>
>




Joe Smith 06-24-2004 08:03 AM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
Daedalus wrote:

> Keep in mind that I'm fresh one week years-old Perl newbie... thanks
> I just need some information about what happen when :
>
> my @string_list; #lets say that this array contain a couple of string, 3:
> qw(the street, a book, theater);
>
> foreach my $string (@string_list){
> if ($string =~ s/(^the\b)|(^a\b)|//i){
> $string_list[++$#string_lis] = $string
> }
> }
>
> When I write: if ($string =~ s/(^the\b)|(^a\b)|//i)..., do I actually
> replacing the string within @string_list (since $string is passed by
> "foreach" from one of the string of @string_list)


Yes. You are modifying the array element as they are being processed
since the foreach variable is aliased to the array element and not
a copy of the array element.

The line inside the if() is better written as
push @string_list, $string;

-Joe

Anno Siegel 06-24-2004 08:40 AM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
Daedalus <daedalus@videotron.ca> wrote in comp.lang.perl.misc:
> "Daedalus" <daedalus@videotron.ca> a écrit dans le message de news:
> BsvCc.530$uY3.534@wagner.videotron.net...


[top-post rearranged]

> > Keep in mind that I'm fresh one week years-old Perl newbie... thanks
> > I just need some information about what happen when :
> >
> > my @string_list; #lets say that this array contain a couple of string,

> 3:
> > (the street, a book, theater)
> >
> > foreach my $string (@string_list){
> > if ($string =~ s/(^the\b)|(^a\b)//i){
> > $string_list[++$#string_lis] = $string
> > }
> > }
> >
> > When I write: if ($string =~ s/(^the\b)|(^a\b)|//i)..., do I actually
> > replacing the string within @string_list (since $string is passed by
> > "foreach" from one of the string of @string_list) I'm asking cause I

> thought
> > that it would add the new strings to the array without touching what was
> > already there. So I would end with this list as @string_list (the street,

> a
> > book, theater, street, book).
> > But when try this, it overwrite and add. So it gives me ( street, book,
> > theater, street, book).
> > What am I doing wrong?

>
> Well I think I was guessing right cause if I write this instead:
>
> foreach (@string_list){
> my $string = $_;
> if ($string =~ s/(^the\b)|(^a\b)//i){


What are the capturing parentheses in the pattern for? s/^the\b|^a\b//i
does the same thing.

> $string_list[++$#string_lis] = $string

^^
Typo here. Don't re-type code, copy/paste it.

Also, "++$#string_list" would be better written as (scalar)
"@string_list".

> }
> }
> I get the wanted result, but I would like someone to confirm that.


Your code (in all variants) has another problem. You are not supposed
to change an array while running a for-loop over it. (See "foreach" in
perlsyn, I suppose.) That it appears to work in this instance doesn't
mean it will with other versions of Perl.

There are lots of ways to repair this, one is

push @string_list, map /(?:the\b|a\b)?\s*(.*)/i, @string_list;

Instead of deleting the unwanted part, this captures the wanted part.
I have also changed the regex so that it also catches trailing
whitespace with the articles.

Anno

Thomas Kratz 06-24-2004 11:59 AM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
Anno Siegel wrote:

>
> Your code (in all variants) has another problem. You are not supposed
> to change an array while running a for-loop over it. (See "foreach" in
> perlsyn, I suppose.) That it appears to work in this instance doesn't
> mean it will with other versions of Perl.


AFAIK you are not supposed to change the array, but changing the aliased
elements should be ok.

so:

push(@array, $_) for @array # not recommended

s/A/B/g for @array # ok

Right?

Thomas

--
open STDIN,"<&DATA";$=+=14;$%=50;while($_=(seek( #J~.> a>n~>>e~.......>r.
STDIN,$:*$=+$,+$%,0),getc)){/\./&&last;/\w| /&&( #.u.t.^..oP..r.>h>a~.e..
print,$_=$~);/~/&&++$:;/\^/&&--$:;/>/&&++$,;/</ #.>s^~h<t< ..~. ...c.^..
&&--$,;$:%=4;$,%=23;$~=$_;++$i==1?++$,:_;}__END__#.... >>e>r^..>l^...>k^..

Anno Siegel 06-24-2004 12:06 PM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
Thomas Kratz <ThomasKratz@REMOVEwebCAPS.de> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
>
> >
> > Your code (in all variants) has another problem. You are not supposed
> > to change an array while running a for-loop over it. (See "foreach" in
> > perlsyn, I suppose.) That it appears to work in this instance doesn't
> > mean it will with other versions of Perl.

>
> AFAIK you are not supposed to change the array, but changing the aliased
> elements should be ok.
>
> so:
>
> push(@array, $_) for @array # not recommended
>
> s/A/B/g for @array # ok
>
> Right?


Right.

Anno

Daedalus 06-24-2004 01:55 PM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
> > if ($string =~ s/(^the\b)|(^a\b)//i){
>
> What are the capturing parentheses in the pattern for? s/^the\b|^a\b//i
> does the same thing.


Actually It was for precedence, I wasn't sure about this \b|^ thing , it
doesn't harm, doesn't it ?
I'll have to familiarize with regexp precedence.


> > $string_list[++$#string_lis] = $string

> ^^
> Typo here. Don't re-type code, copy/paste it.


Sorry I didn't know, but it makes sense to me now.

> Your code (in all variants) has another problem. You are not supposed
> to change an array while running a for-loop over it. (See "foreach" in
> perlsyn, I suppose.) That it appears to work in this instance doesn't
> mean it will with other versions of Perl.


Ok, about this, I wanted the foreach to look at the new string in the array
until there's nothing to add. So if the array start with one string like "to
the bookstore", and the the regexp is s/^to\b|^the\b//i, I would end with 3
string in the array: ("to the bookstore", "the bookstore", "bookstore"). I
need to extract all possible variants, so I don't want to process the array
only once and get rid of everything at the same time. There is probably a
better way to acheive this but that's the only one I found.


> There are lots of ways to repair this, one is
>
> push @string_list, map /(?:the\b|a\b)?\s*(.*)/i, @string_list;
>
> Instead of deleting the unwanted part, this captures the wanted part.
> I have also changed the regex so that it also catches trailing
> whitespace with the articles.


Thank for that. It doesn't act exactly like I want since it would remove "to
the" at the same time, but it just reminds me of that push operator wich I
could use instead of "$string_list[++$#string_lis]" and I just learn the map
operator wich would avoid to overwrite the original array. Well I'm learning
and I like it! But for now (with my little knowledge) i'm still stuck with
writing the array from inside the for foreach.


> Anno




Daedalus 06-24-2004 02:15 PM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 

"Anno Siegel" <anno4000@lublin.zrz.tu-berlin.de> a écrit dans le message de
news: cbeg3h$gii$2@mamenchi.zrz.TU-Berlin.DE...
> Thomas Kratz <ThomasKratz@REMOVEwebCAPS.de> wrote in comp.lang.perl.misc:
> > Anno Siegel wrote:
> >
> > >
> > > Your code (in all variants) has another problem. You are not supposed
> > > to change an array while running a for-loop over it. (See "foreach"

in
> > > perlsyn, I suppose.) That it appears to work in this instance doesn't
> > > mean it will with other versions of Perl.

> >
> > AFAIK you are not supposed to change the array, but changing the aliased
> > elements should be ok.
> >
> > so:
> >
> > push(@array, $_) for @array # not recommended
> >
> > s/A/B/g for @array # ok
> >
> > Right?

>
> Right.


Well the problem is that s///g don't do what I want, since it change every
thing at the same time.
Anyway (for now) it couldn't turn into an infinite loop, since the content
of the loop will inevitably stop adding to the array when it'll stop to find
matches (which is also inevitable, since even if all the words match, the
loop will end with an empty string)
I know it's not the perfect solution (and I'll try to find a better way
while i'm on my learning process), so if someone have any idea... I'd be
glad to correct this misuse.

DAE




Daedalus 06-24-2004 02:37 PM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
> Yes. You are modifying the array element as they are being processed
> since the foreach variable is aliased to the array element and not
> a copy of the array element.


Thanks, since it's an aliase that explain everything.

DAE



Brian McCauley 06-24-2004 04:54 PM

Re: [Newbie] Stupid problem need simple answer (Array & RegExp)
 
"Daedalus" <daedalus@videotron.ca> writes:

> "Anno Siegel" <anno4000@lublin.zrz.tu-berlin.de> a écrit dans le message de
> news: cbeg3h$gii$2@mamenchi.zrz.TU-Berlin.DE...
> > Thomas Kratz <ThomasKratz@REMOVEwebCAPS.de> wrote in comp.lang.perl.misc:
> > > Anno Siegel wrote:
> > >
> > > >
> > > > Your code (in all variants) has another problem. You are not supposed
> > > > to change an array while running a for-loop over it. (See "foreach"

> in
> > > > perlsyn, I suppose.) That it appears to work in this instance doesn't
> > > > mean it will with other versions of Perl.
> > >
> > > AFAIK you are not supposed to change the array, but changing the aliased
> > > elements should be ok.
> > >
> > > so:
> > >
> > > push(@array, $_) for @array # not recommended
> > >
> > > s/A/B/g for @array # ok
> > >
> > > Right?

> >
> > Right.

>
> Well the problem is that s///g don't do what I want, since it change every
> thing at the same time.


If you only want to change the first occurance in each string then
remove the /g.

If you want to append the changed version of the array to the original
array then why not:

s/A/B/g for my @array_copy = @array;
push @array, @array_copy;

> Anyway (for now) it couldn't turn into an infinite loop, since the content
> of the loop...


I asume you are talking about the effect of pushing into @array at the
same time with for().

How do you know that?

Bare in mind that the behaviour of for() when iterating over an array
that grows or shrinks is _undefined_. Undefined means anything could
happen, and also the thing that happens now may not be the thing that
happens in the next version of Perl.

If tomorrow the behaviour of pushing onto the array was to cause the
loop to reset to the start of the array then it could very well create
an infinite loop.

> I know it's not the perfect solution (and I'll try to find a better way
> while i'm on my learning process), so if someone have any idea... I'd be
> glad to correct this misuse.


See several better solutions already given in this thread.

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\


All times are GMT. The time now is 06:52 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.