in reply to Merging multiple variations of a serial number
(The trick is to force backtracking with a (*FAIL) )
And it highlights what hippo already told you: you get two possible results for the case of 13 digits!
IOW you need more filter rules, like ...
And then you must hope there are no more ambiguities left ...
But I think this is a good start.
use v5.12; use warnings; use Data::Dump qw/pp dd/; while (my $l = <DATA>) { chomp $l; my ($n,$desc) = split /\s*=\s*/,$l; say "--- $n"; say " $desc"; my $year = join "|", 18..22; my $month = join "|", 1..9, "01".."12"; my @res; $n =~ /^ (?: (?<year>$year) | (?<month>$month) # no month without year (?<year>$year) )? # date is optional (?<serial>\d{10}) (?<check>\d)? # check is optional $ (?{ push @res, { %+ } }) (*FAIL) /x; say pp \@res; warn "*** TOO MANY MATCHES $n***\n",pp(\@res),"\n\n" if @res > 1; warn "*** NO MATCH $n ***" if @res < 1 } __DATA__ 1231600014 = 10 digit version (just the core serial) 221231600014 = 12 digit version (minus both leading month and last + check digit) 1221231600014 = 13 digit version 2 (minus the leading zero for the +month and minus the check digit). These entries would need to be corr +ected to add the leading zero and therefore become the 14 digit versi +on 2212316000140 = 13 digit version 1 (minus the leading 2 month digit +s but including the last check digit) 01221231600014 = 14 digit version (minus the last check digit) 012212316000140 = Full 15 digit serial. This comprises of month and y +ear (0122), core serial (1231600014), check digit (0)
*** TOO MANY MATCHES 2212316000140*** [ { check => 0, serial => 1231600014, year => 22 }, { month => 2, serial => 2316000140, year => 21 }, ] --- 1231600014 10 digit version (just the core serial) [{ serial => 1231600014 }] --- 221231600014 12 digit version (minus both leading month and last check digit) [{ serial => 1231600014, year => 22 }] --- 1221231600014 13 digit version 2 (minus the leading zero for the month and minus + the check digit). These entries would need to be corrected to add th +e leading zero and therefore become the 14 digit version [{ month => 1, serial => 1231600014, year => 22 }] --- 2212316000140 13 digit version 1 (minus the leading 2 month digits but including + the last check digit) [ { check => 0, serial => 1231600014, year => 22 }, { month => 2, serial => 2316000140, year => 21 }, ] --- 01221231600014 14 digit version (minus the last check digit) [{ month => "01", serial => 1231600014, year => 22 }] --- 012212316000140 Full 15 digit serial. This comprises of month and year (0122), cor +e serial (1231600014), check digit (0) [ { check => 0, month => "01", serial => 1231600014, year => 22 }, ]
Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery
refined the month rules by substituting \d|\d\d with $month = join "|", 1..9, "01".."12";
|
|---|