CrazyDiamond has asked for the wisdom of the Perl Monks concerning the following question:

Hello!
CAN I DELETE OR CLOSE THAT POST?
Answer is: push @data_from, $tmpline =~ /\".*?\"/g;
I'm trying to build a hash slice, but something goes wrong, could you please check it? (It's my 1st post at perlmonks, sry if something's incorrect)
@fields_from=qw|field1 field2 field3 field4 field5 field6 field7 field +8 field9 field10 field11 field12 field13|; ### <FROM> is a text file with 13 field, separated by ';;' while ($tmpline = <FROM>) { chomp ($tmpline); $tmpline =~ s/\s*(\d+);;(.+);;\s*(\d+);;\s*(\d+);;\s*(\d+);;\s*(\d+ +);;\s*(\d+);;\s*(\d+);;\s*(\d+);;(.+?)\s*;;\s*(.*?)\s*;;\s*(\d+);;(.+ +)\s*/"$1", "$2", "$ 3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13"/; ### Pattern always match. @data_from = $tmpline; @from{@fields_from} = @data_from; #Problem is here? while (($key, $value) = each %from) { print "$key => $value\n"; }
Output for single row in file is like that:
field1 => "33", "GS4", "24", "34", "4", "24034004", "1183031", "407785 +", "1", "cc", " zz", "0", "xx" Use of uninitialized value in concatenation (.) or string at ./script. +pl line 159, <FROM> line 2. field2 => Use of uninitialized value in concatenation (.) or string at ./script. +pl line 159, <FROM> line 3. field3 =>
... same for all, exept field1 ! So, why all data in @data_from goest to first element of hash, why its not splitted between all elements?

Replies are listed 'Best First'.
Re: Troubles with building a hash slice
by BrowserUk (Patriarch) on Jan 16, 2008 at 11:56 UTC

    You almost certainly want something like:

    my @data_from = $tmpline =~ m/ \s*(\d+) ;;(.+) ;;\s*(\d+) ;;\s*(\d+) ;;\s*(\d+) ;;\s*(\d+) ;;\s*(\d+) ;;\s*(\d+) ;;\s*(\d+) ;;(.+?) \s*;;\s*(.*?) \s*;;\s*(\d+) ;;(.+)\s* /x;

    That is, use a m// and assign the captures directly to @data_from instead of using s/// and converting it to a string containing the captures which is not an array. You;d need to split it, but that would be pointless.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      hipowls, there is some '\s' in begining and at the end of fields, that i want to remove with pattern match, that's why i didnt use split.
      BrowserUk, thanks! That's much more beutiful, than my s/// & push, with same result!
Re: [SOLVED] Troubles with building a hash slice
by dsheroh (Monsignor) on Jan 16, 2008 at 15:32 UTC
    CAN I DELETE OR CLOSE THAT POST?

    While it is technically possible for you to erase the message body or for monks of a certain level to submit a suggestion that the post be deleted, both actions are frowned upon as they would prevent anyone who may have a similar problem in the future from finding this post and learning from it without repeating the question. (For this reason, if a monk of sufficient level were to consider the post for deletion, I can assure you that the request would be summarily ignored.)

    As for closing/locking the post, some forums are fanatical about that sort of thing. This monastery is not. If someone else were to come by tomorrow, or next week, or even next year with a better solution, then why should they be prevented from suggesting it? Once again, even if you are no longer concerned with improving on the solution, others may see it and learn from it.

Re: Troubles with building a hash slice
by hipowls (Curate) on Jan 16, 2008 at 12:09 UTC

    Your problem is the that $tmpline is a scalar with one value and you are then using it to find the single key '"data1", "data2", ... "data13"'. What you really want to do is the following

    while ( $tmpline = <FROM> ) { chomp $tmpline; @data_from = split ';;', $tmpline; @from{@fields_from} = @data_from; while (($key, $value) = each %from) { print "$key => $value\n"; } }

    As an aside the substitution would have been better written as

    $tmpline =~ s/;;/", "/g; $tmpline = qq{"$tmpline"};