From: Xicheng on
Anno Siegel wrote:
> Xicheng <xicheng(a)gmail.com> wrote in comp.lang.perl.misc:
> > Joe Smith wrote:
> > > Xicheng wrote:
> > >
> > > > If you are working on arrays instead of files, you may try map instead
> > > > of grep, coz the later does nothing on your array elements..
> > >
> > > No, grep does not change array elements.
> > > It's s/// that changes array elements, for both grep and map.
> > > -Joe
> >
> > I guess I didnt make it clear in my original post. here I actually
> > meant that the elements in grep's return-list do not have differences
> > with the corresponding element in the original array. but map's do...
> > that's so-called differences between FILTER and TRANSFER..
>
> That distinction gets blurry when the test function in a filter has
> the side-effect of changing the list element it's looking at, as
> with s///. In that case, the elements that come out of grep may
> not have been among those that went in.
>
> > the returned list of grep(FILTER) may have different number of elements
> > from the original array, but the corresponding elements keep the SAME
> > contents...


> Conceptually, yes. Practically, sometimes not.

yeah, if you count some expressions like s///,tr///, the elements in
the return list may not necessarilly have the same contents as the
corresponing one in the original array.. I didnt notice that, and I
actually have never used those expressions in "grep" before. thanks for
pointing it out to me..:-)

> > the returned list of map(TRANSFER) may have different contents, but
> > generally the number of element are the same except when map-block or
> > expressions return *undefined*....
>
> Oh no. Undefined values are registered nicely with map. The block
> has to return nothing (an empty list) if it doesn't want to contribute
> to the result.

This may come from my experience, when I use:

my @tmp = map {/(sth)/} (list);
print Dumper \@tmp;

and when the map condition are controlled by regex and parenthesis
capturings, I noticed that all the elements which donot satisfy the
condition and thus should register *undefined* in @tmp do not show up
in the printing list of "print Dumper \@tmp". so I supposed these
*undefined* elements are automatically filtered out. you may take a
look at the code I posted in this thread where I did use "map" to
filter out some array elements in the printing result....:)

> > "A..B" expression is not useful for his case, which extracts data by
> > line-mode...
>
> I'm not sure what that means, but scalar .. can certainly be useful
> with grep.

I didnot mean to use it in "grep", and I actually meant using "A..B" as
conditional expression to extract data, i.e.

print $sth if /A/../B/;

which reads/writes data by line-mode unless he resets $/.

Best,
Xicheng

>
> Anno
> --
> $_='Just another Perl hacker'; print +( join( '', map { eval $_; $@ }
> 'use warnings FATAL => "all"; printf "%-1s", "\n"', 'use strict; a',
> 'use warnings FATAL => "all"; "@x"', '1->m') =~
> m|${ s/(.)/($1).*/g; \ $_ }|is),',';

From: Tad McClellan on
Joe Smith <joe(a)inwap.com> wrote:
> Tad McClellan wrote:
>> usenet(a)DavidFilmer.com <usenet(a)DavidFilmer.com> wrote:
>>> I don't believe you can grep over multiple lines,
>>
>> Of course you can.
>
> We're talking about a pattern that takes multiple lines to match.


Yes, I gathered that much.


>> grep() filters a list.
>>
>> If the elements of that list contain multiple lines, then grep()
>> will select on multiple lines.
>
> But if the pattern you're searching for is spread over several
> lines, a simple grep won't match.


Sure it will, if the _list elements_ are spread over several
lines and otherwise match the pattern.

-------------------
#!/usr/bin/perl
use warnings;
use strict;

my @list = ("line\n1\n", "line\n2\n");
foreach my $selected ( grep /e\n2/, @list ) {
print ">>>$selected<<<";
}
-------------------


> ($match_with_s) = $string1 =~ /START(.*)END/s;


Whether the pattern needs an m//s modifier or not is independant
of whether grep can "filter over multiple lines".

(and you probably want non-greedy matching there.)


> @lines = $string1 =~ /(.*\n)/g;
> @match = grep /START(.*)END/, @lines;
> @match_s = grep /START(.*)END/s, @lines;
> @match__ = grep /START(.*)/ .. /(.*)END/, @lines;


But now the elements of the list do not contain multiple lines,
as in the predicate I gave in my followup.


--
Tad McClellan SGML consulting
tadmc(a)augustmail.com Perl programming
Fort Worth, Texas
From: Anno Siegel on
Xicheng <xicheng(a)gmail.com> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
> > Xicheng <xicheng(a)gmail.com> wrote in comp.lang.perl.misc:
> > > Joe Smith wrote:
> > > > Xicheng wrote:

> > > the returned list of map(TRANSFER) may have different contents, but
> > > generally the number of element are the same except when map-block or
> > > expressions return *undefined*....
> >
> > Oh no. Undefined values are registered nicely with map. The block
> > has to return nothing (an empty list) if it doesn't want to contribute
> > to the result.
>
> This may come from my experience, when I use:
>
> my @tmp = map {/(sth)/} (list);
> print Dumper \@tmp;
>
> and when the map condition are controlled by regex and parenthesis
> capturings, I noticed that all the elements which donot satisfy the
> condition and thus should register *undefined* in @tmp do not show up
> in the printing list of "print Dumper \@tmp". so I supposed these
> *undefined* elements are automatically filtered out. you may take a
> look at the code I posted in this thread where I did use "map" to
> filter out some array elements in the printing result....:)

Well, a regex that doesn't capture anything doesn't return undef, it
returns nothing. The difference is subtle and not always noticeable.
If you assign from a non-match

my ( $x) = 'abc' =~ /(X)/;

$x will become undefined, so it looks like that is what the regex returned.
However, when you write

my @x = 'abc' =~ /(X)/;

you'll notice that the list is empty. Similarly, in scalar context

my $x = ();

and

my $x = ( undef);

are indistinguishable by their result, though fundamentally different.
In list context the difference becomes apparent:

my @x = ();
my @x = ( undef);

Anno
--
$_='Just another Perl hacker'; print +( join( '', map { eval $_; $@ }
'use warnings FATAL => "all"; printf "%-1s", "\n"', 'use strict; a',
'use warnings FATAL => "all"; "@x"', '1->m') =~
m|${ s/(.)/($1).*/g; \ $_ }|is),',';
First  |  Prev  | 
Pages: 1 2 3 4
Prev: use library
Next: random fortune cookie