http://qs1969.pair.com?node_id=85960


in reply to Re: Re: pattern matching on a single line
in thread How do I store all matches from a single line?

I thought @second = map EXPR, @first; applied EXPR to each element of @first and placed the results in @second. And since m// doesn't change anything, then @second would equal @first.

So something like:

for (@lines) { @result = /<(.*?)>/g; }


Would be more appropriate.

However, I'm willing to bet heavily that your Perl knowledge far exceeds mine, so I'm wondering: do I misunderstand map or m// (or both)?



FouRPlaY
Learning Perl or Going To die() Trying

Replies are listed 'Best First'.
(bbfu) Re(4): pattern matching on a single line
by bbfu (Curate) on Jun 05, 2001 at 23:33 UTC

    The return value of m/()/g in array context (which map evaluates EXPR in) is the array containing all the matches inside the parentheses, just like in your first reply. The only difference that the map makes is that merlyn is evaluating the m/()/g for every line, while yours only did one line.

    HTH.

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

      Gotcha, I just needed to be more clear. I thought it was implied that they'd have to use that line of code in a loop over each line. I'll make sure I'm more specific next time. Thanks.



      FouRPlaY
      Learning Perl or Going To die() Trying
Re: Re: Re: Re: pattern matching on a single line
by lestrrat (Deacon) on Jun 06, 2001 at 01:13 UTC

    map actually returns the result of EXPR in LIST context. That means each evaluation of

    /<(.*?)>/g

    returns the list of captured items. So in effect we get

    @result = ( ( result of evaluating first element ), ( result of evaluating second element ), ....);

    So the resulting array is one big array with all of the matches that EXPR produced

Re: Re: Re: Re: pattern matching on a single line
by John M. Dlugosz (Monsignor) on Jun 05, 2001 at 23:34 UTC
    He's using map to collect the results into one list. Like foreach, it will iterate over the list specified at the right. But it will also collect together the results into one list. The regex content will return a list of all matches made (thanks to /g), and map will nicely concatenate all those together into one big list.
Re: Re: Re: Re: pattern matching on a single line
by tachyon (Chancellor) on Jun 06, 2001 at 00:22 UTC

    Sadly your example fails to produce the desired result :-( Here are a few different ways to write it, all do the same as Randal's example, which we start with.

    tachyon

    @lines = <DATA>; @result = map /<.*?>/g, @lines; result(1); for (@lines) { @result = /<(.*?)>/g; } result(2); for (@lines){ @match = /<(.*?)>/g; push @result, @match; } result(3); for (@lines){ push @result,$1 while /<(.*?)>/g; } result(4); @result = map{/<.*?>/g}@lines; result(5); sub result { print"\nResults",pop,"\n"; print "$_\n" for @result; @result = (); } __DATA__ aa<aa@aa.com>bb<bb@bb.com>cc<cc@cc.com> dd<dd@dd.dd>ee<ee@ee.com>ff<ff@ff.com>
      Uh, hello? I just ran this code:
      @lines = <DATA>; @result = map /<.*?>/g, @lines; result(1); ### rest deleted ### sub result { print"\nResults",pop,"\n"; print "$_\n" for @result; @result = (); } __DATA__ aa<aa@aa.com>bb<bb@bb.com>cc<cc@cc.com> dd<dd@dd.dd>ee<ee@ee.com>ff<ff@ff.com>
      and it produced this result, which appears perfectly fine:
      Results1 <aa@aa.com> <bb@bb.com> <cc@cc.com> <dd@dd.dd> <ee@ee.com> <ff@ff.com> ### rest deleted
      What part of Sadly your example fails to produce the desired result :-( am I failing to understand?

      -- Randal L. Schwartz, Perl hacker