How can I extract a bunch of numbers from a string?
This is an example of a test file:
Barcode:*99899801000689811*
JSC4000I accountNumber:10006898Sequence Number:998 Envelopes: 1
LCD5010V Using jsl 'CUSOFF' for output page '6'
Barcode:*99999901000673703*
LCD5010V Using jsl 'CUSOFF' for output page '4'
LCD5005V Using job 'A' for current page '4'
So, in this file, how to search for the word Barcode and extract the first five digits of it while simultaneously passing it into an array.
Thanks in advance.
My solution is similar to Manni's, but I recommend using while
to read the file one at a time. You can use substr () like it, but a regex with anchors and no quantifiers will be pretty fast:
my @barcodes;
while (<$ fh>)
{
next unless m / ^ Barcode: \ * ([0-9] {5}) /;
push @barcodes, $ 1;
}
Depending on what else I was doing, I could just use the map. The map expression is in the context of a list, so the m // operator returns a list of things that it matches in any parentheses:
my @barcodes = map { m/^Barcode:\*([0-9]{5})/ } <$fh>;
I suspect any real answer will have a little more code to warn you about lines starting with Barcode:
, but they don't have a number. I haven't been able to find the perfect input file yet :)
The \ G box captures the regex match where you left off with the last match on the same line, in this case just after the colon:
my @barcodes;
while (<$ fh>)
{
next unless m / ^ Barcode: /;
unless (m / \ G \ * ([0-9] {5]) /)
{
warn "Barcode is missing number at line $. \ n";
next;
}
push @barcodes, $ 1;
}
a source to share
Pattern matching in the context of an array returns the values marked (by '(' and ')') as a list. Combine that with the "g" loop modifier to keep re-matching and you can do it all on one line and I like to think very readable.
my $string =<<'HERE';
Barcode:*99899801000689811*
JSC4000I accountNumber:10006898Sequence Number:998 Envelopes: 1
LCD5010V Using jsl 'CUSOFF' for output page '6'
Barcode:*99999901000673703*
LCD5010V Using jsl 'CUSOFF' for output page '4'
LCD5005V Using job 'A' for current page '4'
HERE
my @array = $string =~ m!Barcode:\*([0-9]{5})[0-9]+\*!g;
# or
foreach my $barcode ($string =~ m!Barcode:\*([0-9]{5})[0-9]+\*!g)
{
# do stuff with $barcode
}
a source to share