greenmoss has asked for the wisdom of the Perl Monks concerning the following question:

I wrote a subroutine to strip specified patterns out of an array I passed:
sub remove_pattern_from_array { my $pattern = shift (@_); my @holder_array = qw//; foreach my $line (@_){ unless ($line =~ /$pattern/){ push (@holder_array, $line); } } return @holder_array; }
This works fine. However, I want to parse each line of a supposed aliases file into an array, then make sure all of the elements of the array look like they belong in a unix aliases file:
username: me@you.com
should pass the test, whereas
garbagetest#$^#$^#$%^#$
should fail the test and thus get kicked out of the array

Given the above subroutine, what pattern should I pass to it to make this happen?
I've tried the following:
@aliases_array = remove_pattern_from_array ( "^\$|^#|!(^.+?:\\s+.+\$)", @aliases_array);
The first two alternatives get rid of blank lines and comment lines, but the last part of the pattern isn't picking out only the alias-style lines.

So: what gives?

Replies are listed 'Best First'.
Re: looking for aliases(5)-style entries in a text file
by athomason (Curate) on Aug 17, 2000 at 08:42 UTC
    Looks to me like your routine is reinventing the wheel. Take a look at grep, which handles regexen explicitly. Here's my go at a solution, though I'm not sure of the rules concerning valid alias names, so twiddle with those as appropriate. I'm also making even less of an attempt at verifying the destination address than BlueLines, because that's an entirely different problem. Also remember that things like /dev/null are valid targets.
    #!/usr/bin/perl -w use strict; my @valid = grep { !/^[\w-]+:\s*\S+$/ } <>; # do some stuff with @valid
    If the entire functionality of your program is to strip out the irrelevant lines, this is easier (fore! ;-).

    perl -ne '/^[\w-]+:\s*\S+$/ and print' < /etc/aliases

Re: looking for aliases(5)-style entries in a text file
by BlueLines (Hermit) on Aug 17, 2000 at 03:46 UTC
    why not match what you _do_ want, rather than not matching what you don't want:
    if ($line=~/^\w+:\s+\w+(@\S|)/) { &i_match(); } else { &i_dont_match(); }

    this will also handle local forwards since this is acceptable:
    username: user2
    Update:this _wont_ handle email addresses correctly (i just blindly grab everything after the @ and assume it's correct. To correctly check for valid email addresses, look here.

    BlueLines

    Disclaimer: This post may contain inaccurate information, be habit forming, cause atomic warfare between peaceful countries, speed up male pattern baldness, interfere with your cable reception, exile you from certain third world countries, ruin your marriage, and generally spoil your day. No batteries included, no strings attached, your mileage may vary.