2015-03-03 1 views
1

J'essaie du code en utilisant Tie :: Handle :: CSV, mais je suppose que cela pourrait être fait en utilisant d'autres modules ou pas du tout. Ce que je veux faire est de prendre un fichier de mise en page aléatoire et le faire correspondre à ce que je prédis que les en-têtes seront. Ensuite, je veux l'arranger à ma structure de table.Parse CSV basé sur la disposition d'en-tête aléatoire perl

DONNÉES

Prénom, nom, date de naissance
Jim, Johansen, 08/25/1989

OU

2ème Nom, 1er nom, date de naissance
Johansen , Jim, 08/25/1989

OU

2ème Nom, 1er nom, D.O.B, ville, comté
Johansen, Jim 08/25/1989, milwaukee, N/A

Comme vous pouvez le voir, j'ai différentes structures de données. Je veux qu'il les arrange dans mon schéma, même si les champs que je demande sont vides. La façon dont je veux faire ceci est en recherchant mon entrée avec mes variables de colonne.

Voici ce que j'essaie.

code

use Tie::Handle::CSV; 
my $name1 =qr/First Name|Name|1st Name/i; 
my $name2 =qr/Last Name|Maiden Name|2nd Name/i; 
my $date_of_birth =qr/date of birth|D.O.B/i; 
my $city =qr/city|town/i; 
    my $csv_fh = Tie::Handle::CSV->new('list.txt', header => 1); 
    while (my $csv_line = <$csv_fh>) 
     { 
     print $csv_line->{'$date_of_birth'}.",".$csv_line->{'$name1'}." ".$csv_line->{'$name2'}.",".$csv_line->{'$city'}.\n"; ##note I am searching for the column {$'colummn regex'} instead of {'column'} to see if my input file matches any of the header options. 
     } 
    close $csv_fh; 

Ma sortie est vide car ce module est de ne pas comprendre le regex j'implémentez. Cependant, ma sortie contiendrait les colonnes spécifiées si je leur nom littéral, à savoir

La eteint je veux serait:

Scénario 1

Date de naissance, son nom, ## mon en-tête implémenté
08/25/1989, Jim Johansen, ## notant aussi que s'il n'y a pas de 'ville' dans les données d'entrée, laissez vide.

Scénario 2

Date de naissance, son nom, ## ma tête mis en œuvre
08/25/1989, Jim Johansen,

Scénario 3 Date de naissance, nom, Ville ## mon en-tête mis en œuvre
08/25/1989, Jim Johansen, milwaukee

Peut-être qu'il y a une meilleure option qu'un module ou même mon reg variables ex. Quelqu'un at-il dû analyser les csv dans des mises en page en constante évolution?

+0

La plupart des analyseurs CSV ont des options qui incluent un en-tête comme premier enregistrement. Cela donne généralement le nombre de colonnes. Vous pouvez toujours analyser les enregistrements vous-même et extraire n'importe quelle colonne, en fonction des données de terrain que vous pourriez examiner avec vos expressions régulières. – sln

+0

Une autre approche consiste à configurer une base de données relationnelle dans laquelle vous conservez les données d'origine dans des tables distinctes et créez la table déduite avec les requêtes SELECT ... UNION (ou INSERT ... SELECT) . De cette façon, vous pouvez toujours faire des erreurs dans vos inférences. Vous pouvez utiliser ['DBD :: CSV'] (http://search.cpan.org/perldoc?DBD::CSV) pour lire les tables et [' DBD :: SQLite'] (http: //search.cpan .org/perldoc? DBD :: SQLite) pour créer la base de données. – reinierpost

Répondre

3

Vous n'utilisez jamais $name1, $name2, etc, et encore moins dans un opérateur de correspondance (ou de substitution), donc vous exécutez jamais une correspondance regex.

my $field_names = $csv_fh->header(); 

my ($name1_header) = grep /First Name|^Name$|1st Name/i,  @$field_names; 
my ($name2_header) = grep /Last Name|Maiden Name|2nd Name/i, @$field_names; 
my ($dob_header ) = grep /date of birth|D\.O\.B/i,   @$field_names; 
my ($city_header) = grep /city|town/i,      @$field_names; 

my @recognized_fields = ($name1_header, $name2_header, $dob_header, $city_header); 
my %recognized_fields = map { $_ => 1 } @recognized_fields; 
my @other_headers = grep !$recognized_fields{$_}, @$field_names; 

while (my $row = <$csv_fh>) { 
    my $name1 = $name1_header ? $row->{$name1_header} : undef; 
    my $name2 = $name2_header ? $row->{$name2_header} : undef; 
    my $dob = $dob_header ? $row->{$dob_header } : undef; 
    my $city = $city_header ? $row->{$city_header } : undef; 

    my @other_fields = @$row{@other_headers}; 

    ... 
} 
+0

Et s'il n'y a pas d'en-tête à lire ou que l'en-tête ne correspond pas à la disposition donnée, et que je veux mettre ces lignes dans un fichier séparé? @ikegami – JDE876

+0

Ajouté à la réponse. – ikegami