.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Data::TableReader::Field 3pm" .TH Data::TableReader::Field 3pm "2020-08-20" "perl v5.30.3" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Data::TableReader::Field \- Field specification for Data::TableReader .SH "VERSION" .IX Header "VERSION" version 0.011 .SH "DESCRIPTION" .IX Header "DESCRIPTION" This class describes aspects of one of the fields you want to find in your spreadsheet. .SH "ATTRIBUTES" .IX Header "ATTRIBUTES" .SS "name" .IX Subsection "name" Required. Used for the hashref key if you pull records as hashes, and used in diagnostic messages. .SS "header" .IX Subsection "header" A string or regex describing the column header you want to find in the spreadsheet. If you specify a regex, it is used directly. If you specify a string, it becomes the regex matching any string with the same words (\ew+) and non-whitespace (\eS+) characters in the same order, case insensitive, surrounded by any amount of non-alphanumeric garbage (\f(CW\*(C`[\eW_]*\*(C'\fR). When no header is specified, the \*(L"name\*(R" is used as a string after first breaking it into words on underscore or camel-case or numeric boundaries. .PP This deserves some examples: .PP .Vb 5 \& Name Implied Default Header \& "zipcode" "zipcode" \& "ZipCode" "Zip Code" \& "Zip_Code" "zip Code" \& "zip5" "zip 5" \& \& Header Regex Could Match... \& "ZipCode" /^[\eW_]*ZipCode[\eW_]*$/i "zipcode:" \& "zip_code" /^[\eW_]*zip_code[\eW_]*$/i "\-\-ZIP_CODE\-\-" \& "zip code" /^[\eW_]*zip[\eW_]*code[\eW_]*$/i "ZIP\enCODE " \& "zip\-code" /^[\eW_]*zip[\eW_]*\-[\eW_]*code[\eW_]*$/i "ZIP\-CODE:" \& qr/Zip.*Code/ /Zip.*Code/ "Post(Zip)Code" .Ve .PP If this default matching doesn't meet your needs or paranoia level, then you should always specify your own header regexes. .PP (If your data actually doesn't have any header at all and you want to brazenly assume the columns match the fields, see reader attribute \*(L"header_row_at\*(R" in Data::TableReader) .SS "required" .IX Subsection "required" Whether or not this field must be found in order to detect a table. Defaults is \fBtrue\fR. Note this does \fBnot\fR require the field of a row to contain data in order to read a record from the table; it just requires a column to exist. .SS "trim" .IX Subsection "trim" .Vb 2 \& # remove leading/trailing whitespace \& trim => 1 \& \& # remove leading/trailing whitespace but also remove "N/A" and "NULL" \& trim => qr( ^ \es* N/A \es* $ | ^ \es* NULL \es* $ | ^ \es+ | \es+ $ )xi \& \& # custom search/replace in a coderef \& trim => sub { s/[\e0\-\e1F\e7F]+/ /g; s/^\es+//; s/\es+$//; }; .Ve .PP If set to a non-reference, this is treated as a boolean of whether to remove leading and trailing whitespace. If set to a coderef, the coderef will be called for each value with \&\f(CW$_\fR set to the current value; it should modify \f(CW$_\fR as appropriate (return value is ignored). It can also be set to a regular expression of all the patterns to remove, as per \&\f(CW\*(C`s/$regexp//g\*(C'\fR. .PP Default is \fB1\fR, which is equivalent to a regular expression of \f(CW\*(C`qr/(^\es+)|(\es+$)/\*(C'\fR. .SS "blank" .IX Subsection "blank" The value to extract when the spreadsheet cell is an empty string or undef. (after any processing done by \*(L"trim\*(R") Default is \f(CW\*(C`undef\*(C'\fR. Another common value would be \f(CW""\fR. .SS "type" .IX Subsection "type" A Type::Tiny type (or any object or class with a \f(CW\*(C`validate\*(C'\fR method) or a coderef which returns a validation error message (undef if it is valid). .PP .Vb 3 \& use Types::Standard; \& ... \& type => Maybe[Int] \& \& # or without Type::Tiny \& type => sub { $_[0] =~ /^\ew+/? undef : "word\-characters only" }, .Ve .PP This is an optional feature and there is no default. The behavior of a validation failure depends on the options to TableReader. .SS "array" .IX Subsection "array" Boolean of whether this field can be found multiple times in one table. Default is \fBfalse\fR. If true, the value of the field will always be an arrayref (even if only one column matched). .SS "follows" .IX Subsection "follows" Name (or arrayref of names) of a field which this field must follow, in a first-to-last ordering of the columns. This field must occur immediately after the named field(s), or after another field which also has a \f(CW\*(C`follows\*(C'\fR restriction and follows the named field(s). .PP The purpose of this attribute is to resolve ambiguous columns. Suppose you expect columns with the following headers: .PP .Vb 2 \& Father | | | | Mother | | | \& FirstName | LastName | Tel. | Email | FirstName | LastName | Tel. | Email .Ve .PP You can use \f(CW\*(C`qr/Father\enFirstName/\*(C'\fR to identify the first column, but after FirstName the rest are ambiguous. But, TableReader can figure it out if you say: .PP .Vb 5 \& { name => \*(Aqfather_first\*(Aq, header => qr/Father\enFirstName/ }, \& { name => \*(Aqfather_last\*(Aq, header => \*(AqLastName\*(Aq, follows => \*(Aqfather_first\*(Aq }, \& { name => \*(Aqfather_tel\*(Aq, header => \*(AqTel.\*(Aq, follows => \*(Aqfather_first\*(Aq }, \& { name => \*(Aqfather_email\*(Aq, header => \*(AqEmail\*(Aq, follows => \*(Aqfather_first\*(Aq }, \& .. .Ve .PP and so on. Note how \f(CW\*(Aqfather_first\*(Aq\fR is used for each as the \f(CW\*(C`follows\*(C'\fR name; this way if any non-required fields (like maybe \f(CW\*(C`Tel\*(C'\fR) are completely removed from the file, TableReader will still be able to find \f(CW\*(C`LastName\*(C'\fR and \f(CW\*(C`Email\*(C'\fR. .PP You can also use this to accumulate an array of columns that lack headers: .PP .Vb 2 \& Scores | | | | | | | OtherData \& 12% | 35% | 42% | 18% | 65% | 99% | 55% | xyz \& \& { name => \*(Aqscores\*(Aq, array => 1, trim => 1 }, \& { name => \*(Aqscores\*(Aq, array => 1, trim => 1, header => \*(Aq\*(Aq, follows => \*(Aqscores\*(Aq }, .Ve .PP The second field definition has an empty header, which would normally make it rather ambiguous and potentially capture blank-header columns that might not be part of the array. But, because it must follow a column named 'scores' there's no ambiguity; you get exactly any column starting from the header \f(CW\*(AqScores\*(Aq\fR until a column of any other header. .SS "follows_list" .IX Subsection "follows_list" Convenience accessor for \f(CW\*(C`@{ \->follows }\*(C'\fR, useful because \f(CW\*(C`follows\*(C'\fR might only be a scalar. .SS "header_regex" .IX Subsection "header_regex" \&\*(L"header\*(R", coerced to a regex if it wasn't already .SH "AUTHOR" .IX Header "AUTHOR" Michael Conrad .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2019 by Michael Conrad. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.