in reply to Re: Re: Re: Re: Match key and return value in some order
in thread Match key and return value in some order

First problem is that there is a typo in the code you posted. When doing the substitution, you had for qkeys %questionlookup; instead of keys.

However, I don't think that is the real problem as your code wouldn't compile without correcting this. So that leaves a second possibility - the format of your patterns file is not quite the same as I used in my answer.

Please go back to that answer and note the comment

#! Added leading and removed trailing /'s for consistancy

I slightly modified the format of your patterns as you supplied them as this made the format more consistent which greatly simplified the regexes used for parsing them.

As I don't have access to your patterns file, I re-used the (modified) versions that you supplied for the original question in the attached code. Using this, and with the correction above, your program works fine.

I'm afraid that if your existing patterns file omits the /'s on the first tag and includes a trailing / on the end, then you wil either have to

I think that doing the former would be easier, as well as giving a more consistant format, but only you will know the scale of the problem and how easy that modification would be to do, so that decision is yours.

Code and output

#! perl -sw use Data::Dumper; use strict; local $\=$/; =pod Note! This is a comment only!! my %patterns; open(PFILE, "whatpattern.txt")|| die "Cannot open whatpattern.txt file +"; while (<PFILE>) { chomp; next unless $_; my @tags = split /; |:/; my $key = shift @tags; $patterns{$key} = \@tags; } open(TESTFILE, "alltestfile")|| die "Cannot open alltestfile"; =cut my %patterns = ( '/WRB1/JJ1/VBZ1/NP1/IN1/NP2' => '/NP1/VBZ1(so)/JJ1 : /NP1/IN +1/NP2/VBZ1(really)/JJ1', '/WP/NP1/VB1/VBN1/PP1' => '/PP1/PP2/NP1(are)/VB1', ); while(defined(my $question=<DATA>)) { my @qkeys = $question =~ m!(/[A-Z0-9]+)!g; my @qvalues = $question =~ m!(.*?)(?:/[A-Z0-9]+\s+)!g; my %questionlookup; @questionlookup{@qkeys} = @qvalues; my $key = join'',@qkeys; print $question."\n\n"; if (my $answer = $patterns{$key}) { #! You had a syntax error here--------------------v !!!!!!!!!! +! #! $answer =~ s!\s*$_\s*! $questionlookup{$_} !g for qkeys %que +stionlookup; $answer =~ s!\s*$_\s*! $questionlookup{$_} !g for keys %questi +onlookup; $answer =~ s/\:/\n\n/g; print $answer; } else { print "No Match\n"; } } __DATA__ How/WRB1 hot/JJ1 is/VBZ1 the core/NP1 of/IN1 the earth/NP2 ?/

Output:

C:\test>perl -c 210275.pl Operator or semicolon missing before %questionlookup at 210275.pl line + 38. Ambiguous use of % resolved as operator % at 210275.pl line 38. Bareword "qkeys" not allowed while "strict subs" in use at 210275.pl l +ine 38. Bareword "questionlookup" not allowed while "strict subs" in use at 21 +0275.pl line 38. 210275.pl had compilation errors. C:\test>perl -c 210275.pl 210275.pl syntax OK C:\test>210275 How/WRB1 hot/JJ1 is/VBZ1 the core/NP1 of/IN1 the earth/NP2 ?/ the core is (so) hot the core of the earth is (really) hot C:\test>

Nah! Your thinking of Simon Templar, originally played by Roger Moore and later by Ian Ogilvy

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Re: Match key and return value in some order
by Anonymous Monk on Nov 04, 2002 at 22:26 UTC
    Hello Monk

    Thanks for your answer but I double checked my patterns and they have the same format with /'s at the beginning of the tag and not / at the end, I even create a file with just one pattern, the one we have been using so far and it still showing me the same
    For each question that match, the result is ARRAY(0x81527ec) btw I corrected the errors you mentioned, and as you said this was not the problem...

    I don't know what to do, I read other post about people having the same results and it was a problem of reference but I tried the same and it did not work for me!!

    Thanks

      Ok. I now see the problem.

      while (<PFILE>) { chomp; next unless $_; my @tags = split /; |:/; my $key = shift @tags; $patterns{$key} = \@tags; ## <<< HERE }
      When you are building your %patterns hash, you are reading the tagged data into an array and then assigning a reference to that array as the value in your hash.

      (I didn't encounter the problem because I bypassed this piece of code as I don't have your datafile.)

      There are two ways around the problem depending on how you use the data later. If you don't need to access the array's elements individually in other parts of the code, you can convert the array to a scalar when you assign it to the hash. That means substituing the following line for the one I flagged in the code above.

      $patterns{$key} = "@tags";

      That will convert the array to a scalar and the rest of the program should then work.

      However, if you need to use the array as an array elsewhere in your program, then you will need to modify the code that builds the second hash.

      If this is needed and you have trouble with it, come back with your attempt at the code to do this, and I'll try and help you further.


      Nah! Your thinking of Simon Templar, originally played by Roger Moore and later by Ian Ogilvy
        Thank you very much!!!

        It works!! the only thing is that it doesn't split the results in lines, but I am happy.
        About the second hash, I will start working on that in case I need the arrays from my patterns later ;)
        Great!! Thanks