pattern 1: 1=2 2=3 0=-1
pattern 2: 1=2 3=4
pattern 3: 3=4 5=2
####
# PART 1: Per-column pattern-matching values
# when this column ...
# has this value ...
# count it as a column match toward these pats ...
0 => { -1 => [ 'pattern 1' ] },
1 => { 2 => [ 'pattern 1', 'pattern 2' ] },
2 => { 3 => [ 'pattern 1' ] },
3 => { 4 => [ 'pattern 2', 'pattern 3' ] },
5 => { 2 => [ 'pattern 3' ] }
# PART 2: Pattern sizes
# this pattern ...
# requires this many column matches ...
'pattern 1' => 3,
'pattern 2' => 2,
'pattern 3' => 2
##
##
my %pattern_colvals;
my %pattern_sizes;
# convert pattern specs into internal representation
while () {
my ($pattern, $spec) = split /:\s*/, $_, 2;
my @col_patterns = map [split /=/], split ' ', $spec;
$pattern_sizes{$pattern} = @col_patterns;
for (@col_patterns) {
my ($col, $match_val) = @$_;
push @{$pattern_colvals{$col}{$match_val}}, $pattern;
}
}
##
##
# parse input CSV file and check for matches against patterns
while (<>) {
chomp;
my @col_vals = split /,/; # use real CSV parsing instead
my ($col, %col_matches);
for (@col_vals) {
for (@{ $pattern_colvals{$col++}{$_} }) {
print "line $. matches $_$/"
if ++$col_matches{$_} == $pattern_sizes{$_};
}
}
}
##
##
$ { echo -1,2,3,4,5,6
echo -1,2,4,0,0,9
echo 0,0,0,4,3,2
} | perl pm-patterns.pl
line 1 matches pattern 1
line 1 matches pattern 2
line 3 matches pattern 3