|
Prev: use library
Next: random fortune cookie
From: Xicheng on 12 Feb 2006 16:48 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 12 Feb 2006 23:31 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 13 Feb 2006 03:43
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),','; |