Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!usc!elroy.jpl.nasa.gov!decwrl!orc!mipos3!iwarp.intel.com!news From: merlyn@iwarp.intel.com (Randal Schwartz) Newsgroups: comp.lang.perl Subject: Re: Bug or misunderstanding? Message-ID: <1990Feb27.174836.21449@iwarp.intel.com> Date: 27 Feb 90 17:48:36 GMT References: <2860@uvaarpa.virginia.edu> Sender: news@iwarp.intel.com Reply-To: merlyn@iwarp.intel.com (Randal Schwartz) Organization: Stonehenge; netaccess via Intel, Beaverton, Oregon, USA Lines: 99 In-Reply-To: alfie%cs.warwick.ac.uk@nsfnet-relay.ac.uk (Nick Holloway) In article <2860@uvaarpa.virginia.edu>, alfie%cs (Nick Holloway) writes: | [I am sending this via mailing list, since news is a bit dodgy here] | | I am trying to split an array into two arrays. One will contain any | elements that match any pattern in a pattern array, and the other | contains all others. Here is the section of code that is causing me | grief: | | @text = ( "Hello", "Joe", "Schmoe", "Gordon" ); | @pat = ( "e", "o" ); | text: for $text ( @text ) { | for $pat ( @pat ) { | if ( $text =~ /$pat/i ) { | print "Match: $pat: $text\n"; | next text; | } | } | print "NoMatch: $text\n"; | } | | I know that I am using the same name in different contexts, but arrays, | constants and labels should have a separate namespace (right?). | | The problem seems to be with the "next text;" line. I need that there, | since otherwise elements may be matched with more than one pattern. I | can't use a "last;" just to skip the rest of the patterns, coz I need | to keep elements that do not match. However, the above code does not | work as expected. Here is the sample output | | Match: e: Hello | Match: o: Joe | NoMatch: Schmoe | Match: o: Gordon | | Note that "Joe" did not match on the "e" but on the "o", and "Schmoe" didn't | match at all! | | Have I misunderstood something vital? This is my first attempt to use | labelled "next/last"s, and it is possible I have missed something in | the manual. If so, I am open to suggestions of better ways of doing | it. Perhaps if I spell Randal's name wrong, he'll give me a one liner :-) | At the moment, I am inclined to think it is a bug. Well, here's the one-liner (but you spelled my name right): @hasit = grep(/e/i,@text); @neverhaditneverwill = grep(!/e/i, @text); I got the same results as you running your code on a Sun3 rev 6. Your code should have worked (methinks). Larry? As a workaround (read: kludge), I got the right results with the following putziness: @text = ( "Hello", "Joe", "Schmoe", "Gordon" ); @pat = ( "e", "o" ); for $text ( @text ) { inner: { for $pat ( @pat ) { if ( $text =~ /$pat/i ) { print "Match: $pat: $text\n"; last inner; } } print "NoMatch: $text\n"; } } I use labled blocks quite a bit. Like, for a "loop...end loop" sorta construct, instead of the C-like idiom of: LOOP: while (1) { ... ... last LOOP if some_condition; ... ... } I use: LOOP: { ... ... last LOOP if some_condition; ... ... redo LOOP; } I guess I don't like to see that funky '1' there when it isn't being evaluated. No, I haven't looked at the code to see if it actually got optimized away. for (split(/(.)/,"Just another Perl hacker,")) {print if $_;} -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/