On Fri, 24 Oct 2008 12:50:23 +0800,
Amy Lee <> wrote:
> Hello,
>
> I use qw to make a list with
> my @sample = qw/"A..." "A..+" "A.+." "A+.." "A.++" "A+.+" "A++." "A+++"/;
> Then there's a list called @ar and I want check whether the element at
> @sample belongs to @ar. So I wrote the following codes
> foreach my $item_sample (@sample)
> {
> unless (grep /$item_sample/, @ar) #line 38
> {
> push @ar, "$item_sample";
> }
> }
> But wehn I run my script it shows following error messages
> Nested quantifiers in regex; marked by <-- HERE in m/"A.++ <-- HERE "/
> at ./x.pl line 38, <> line 44.
>
> So I really feel very confused about it. Could you tell me why it happens
> and how can I fix that?
In the above $item_sample is being treated as a regular expression. A
few of the things in @sample are simply not valid regular expressions. I
am assuming that you actually didn't mean them to be regular
expressions and that you wanted to check for string equality.
Also, are you aware that the strings you're looking at have double
quotes in them as well? Did you mean them to have those quotes in them?
There are a few ways in which you can fix this.
The minimal change is to correctly quote any metacharacters in the
regular expression (see the perlre documentation)
Change one line (your line 3

:
unless (grep /\Q$item_sample/, @ar) #line 38
This does, however, probably not the right thing. It checks whether
$item_sample is PART of one of the elements of @ar. If you had "A+++"
and "A++" in that order in @sample, the second element would not end up
in @ar. I doubt that that was intentional.
You could anchor the regex at the start and end, but it would probably
be better to simply say what (I think) you mean, and test for equality:
unless (grep {$_ eq $item_sample} @ar) #line 38
This still is rather inefficient, because you have to loop through the
whole of @ar for every element of @sample. For small arrays that makes
no difference, but for larger arrays that is a problem.
I think that what you're trying to do is to assign the unique elements
of @sample to @ar, right? The canonical way to do that in Perl is by
using a hash:
my %seen;
my @ar = grep { ! $seen{$_}++ } @sample;
(Note that grep is used here only ones. These two lines are meant to
replace all the code you quoted above, not just line 38.)
Also check out the perlFAQ entry in perlfaq4 with the title "How can I
remove duplicate elements from a list or array?" This entry also
descibes this method with an explicit loop, instead of grep, which you
might find easier.
Martien
--
|
Martien Verbruggen | Quick! Hire a teenager while they still know
| everything.
|