Take me over?
NAME
Parse::FixedLength - parse an ascii string containing fixed length fields into component parts
SYNOPSIS
use Parse::FixedLength;
$parser = Parse::FixedLength->new(\@format);
$parser = Parse::FixedLength->new(\@format, \%parameters);
$hash_ref = $parser->parse($data);
$data = $parser->pack($hash_ref);
$converter = $parser1->converter($parser2);
$converter = $parser1->converter($parser2, \%mappings);
$converter = $parser1->converter($parser2, \@mappings);
$converter = $parser1->converter($parser2, \%mappings, \%defaults);
$converter = $parser1->converter($parser2, \@mappings, \%defaults);
$data_out = $converter->convert($data_in);
DESCRIPTION
The Parse::FixedLength
module facilitates the process of breaking a string into its fixed-length components.
PARSING ROUTINES
- new()
-
$parser = Parser::FixedLength->new(\@format) $parser = Parser::FixedLength->new(\@format, \%parameters)
This method takes an array reference of field names and lengths as either alternating elements, or delimited args in the same field, e.g.:
my $parser = Parse::FixedLength->new([ first_name => 10, last_name => 10, address => 20, ]); or: my $parser = Parse::FixedLength->new([qw( first_name:10 last_name:10 address:20 )]);
If the first format is chosen, then no delimiter characters may appear in the field names (see delim option below).
To right justify a field (during the 'pack' method), an "R" may be appended to the length of the field along with (optionally) the character to pad the string with (if no character follows the "R", then a space is assumed). This is somewhat inefficient, so its only recommended if actually necessary to preserve the format during operations such as math or converting format lengths. If its not needed but you'd like to specify it anyway for documentation purposes, you can use the no_justify option below. Also, it does change the data in the hash ref argument.
An optional hash ref may also be supplied which may contain the following:
delim - The delimiter used to separate the name and length in the format array. If another delimiter follows the length then the next two fields are assumed to be start and end position, and after that any 'extra' fields are ignored. The default delimiter is ":". The package variable DELIM may also be used. autonum - This option controls the behavior of new() when duplicate field names are found. Normally the a fatal error will be generated if duplicate field names are found. If you have, e.g., some unused filler fields, then as the value to this option, you can either supply an arrayref containing valid duplicate names or a simple true value to accept all duplicate values. If there is more than one duplicate field, then when parsed, they will be renamed '<name>_1', '<name>_2', etc. spaces - If true, preserve trailing spaces during parse. no_justify - If true, ignore the "R" format option during pack. no_validate - By default, if two fields exist after the length argument in the format (delimited by whatever delimiter is set), then they are assumed to be the start and end position (starting at 1), of the field, and these fields are validated to be correct, and a fatal error will be generated if they are not correct. If this option is true, then the start and end are not validated. debug - Print field names and values during parsing (as a quick format validation check). The package variable DEBUG may also be used.
- parse()
-
$hash_ref = $parser->parse($string) @ary = $parser->parse($string)
This function takes a string and returns the results of fixed length parsing as a hash reference of field names and values if called in scalar context, or just a list of the values if called in list context.
- pack()
-
$data = $parser->pack(\%data_to_pack);
This function takes a hash reference of field names and values and returns a fixed length format output string.
- names()
-
$ary_ref = $parser->names;
Return an ordered arrayref of the field names.
- length()
-
$tot_length = $parser->length; $field_length = $parser->length($name);
Returns the total length of all the fields, or of just one field name. E.g.:
while (read FH, $data, $parser->length) { $parser->parse($data); ... }
- dumper()
-
$parser->dumper($pos_as_comments);
Returns the parser's format layout information in a format suitable for cutting and pasting into the format array argument of a Parse::FixedFormat->new() call, and includes the start and end positions of all the fields (starting with position 1). If a true argument is supplied then it will include the start and ending positions as comments. E.g.:
# Assume the parser is from the ones defined in the new() example: print $parser->dumper(1); produces for first example: first_name => 10, # 1-10 last_name => 10, # 11-20 address => 20, # 21-40 or for the second example: print $parser->dumper; first_name:10:1:10 last_name:10:11:20 address:20:21:40
- converter()
-
$converter = $parser1->converter($parser2); $converter = $parser1->converter($parser2, \%mappings); $converter = $parser1->converter($parser2, \@mappings); $converter = $parser1->converter($parser2, \%mappings, \%defaults); $converter = $parser1->converter($parser2, \@mappings, \%defaults);
Returns a format converting object. $parser1 is the parsing object to convert from, $parser2 is the parsing object to convert to.
By default, common field names will be mapped from one format to the other. Fields with different names can be mapped from the first format to the other (or you can override the default) using the second argument. The keys are the source field names and the corresponding values are the target field names. This argument can be a hash ref or an array ref since you may want to map one source field to more than one target field.
Defaults for any field in the target format can be supplied using the third argument, where the keys are the field names of the target format, and the value can be a scalar constant, or a subroutine reference where the first argument is simply the mapped value (or the empty string if there was no mapping), and the second argument is the entire hash reference that results from parsing the data with the 'from' parser object. E.g. if you were mapping from a separate 'zip' and 'plus_4' field to a 'zip_plus_4' field, you could map 'zip' to 'zip_plus_4' and then supply as one of the key/value pairs in the 'defaults' hash ref the following:
zip_plus_4 => sub { shift() . $_[0]{plus_4} }
- convert()
-
$data_out = $converter->convert($data_in); $data_out = $converter->convert(\%hash);
Converts a string or a hash reference from one fixed length format to another.
EXAMPLES
use Parse::FixedLength;
my $parser = Parse::FixedLength->new([
first_name => 10,
last_name => 10,
widgets_this_month => '5R0',
]);
# Do a simple name casing of names
# and print widgets projected for the year for each person
while (<DATA>) {
warn "No record terminator found!\n" unless chomp;
warn "Short Record!\n" unless $parser->length == length;
my $data = $parser->parse($_);
# See Lingua::EN::NameCase for a real attempt at name casing
s/(\w+)/\u\L$1/g for @$data{qw(first_name last_name)};
$data->{widgets_this_month} *= 12;
print $parser->pack($data), "\n";
}
__DATA__
BOB JONES 00024
JOHN SMITH 00005
JANE DOE 00007
Another way if we're converting formats:
my $parser1 = Parse::FixedLength->new([
first_name => 10,
last_name => 10,
widgets_this_month => '5R0',
]);
# Use delim option just for example
my $parser2 = Parse::FixedLength->new([qw(
seq_id:10
first_name:10
last_name:10
country:3
widgets_this_year:10R0
)]);
my $converter = $parser1->converter($parser2, {
widgets_this_month => widgets_this_year,
},{
seq_id => do { my $cnt = '0' x $parser2->length('seq_id');
sub { ++$cnt };
},
widgets_this_year => sub { 12 * shift },
country => 'USA',
});
while (<DATA>) {
warn "No record terminator found!\n" unless chomp;
warn "Short Record!\n" unless $parser1->length == length;
print $converter->convert($_), "\n";
}
AUTHOR
Douglas Wilson <dougw@cpan.org>
original by Terrence Brannon <tbone@cpan.org>
COPYRIGHT
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.