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

Hi Monks

I have a hash of array made of part_of_speech tags, being keys: WP/NP1/VB1/RB1/PP1/PP2... and each key is associated with an array of 1 or n set of tags (the same as the key) but in different order, and optional values between (), value are separated by colons :

key 1: WRB1/JJ1/VBZ1/NP1/IN1/NP2/ ; value: NP1/VBZ1/(so)/JJ1 : NP1/IN1/NP2/VBZ1/(really)/JJ1
key 2: WP/NP1/VB1/VBN1/PP1/ value: PP1/PP2/NP1/(are)/VB1/

My question is the following: having an array of questions, like
How/WRB1 hot/JJ1 is/VBZ1 the core /NP1 of/IN1 the earth /NP2 ?/

I extract for each question the tags (key-question) and compare with hash of arrays, and if it match one of the key
How will I extract the value from my hash of array, and take each set of tags, and look into the question to generate sentences (in another file) in the same order the set of tags indicated plus the optional values? so...

The answer will be: the core is (so) hot, and the core of the earth is (really) hot.
Thanks in advance!!
  • Comment on Match key and return value in some order

Replies are listed 'Best First'.
Re: Match key and return value in some order
by BrowserUk (Patriarch) on Nov 04, 2002 at 00:30 UTC

    I tweaked your answer format a little to simplify things. See comment below.

    #! perl -sw use strict; local $\=$/; #! Added leading and removed trailing /'s for consistancy my %answers = ( '/WRB1/JJ1/VBZ1/NP1/IN1/NP2' => '/NP1/VBZ1(so)/JJ1 : /NP1/IN1/N +P2/VBZ1(really)/JJ1', '/WP/NP1/VB1/VBN1/PP1' => '/PP1/PP2/NP1(are)/VB1', ); my $question = 'How/WRB1 hot/JJ1 is/VBZ1 the core/NP1 of/IN1 the earth +/NP2 ?/'; my @keys = $question =~ m!(/[A-Z0-9]+)!g; # Parse markers # Update: Fixed problem not capturing all words between tags #my @values = $question =~ m!(\w+)(?=/)!g; # Parse values my @values = $question =~ m!(.*?)(?:/[A-Z0-9]+\s+)!g; my %lookup; @lookup{@keys} = @values; # Build lookup my $key = join'',@keys; my $answer = $answers{$key}; $answer =~ s!\s*$_\s*! $lookup{$_} !g for keys %lookup; $answer =~ s!\s+:\s+! and the !g; #$answer = 'The' . $answer; # Update: No longer needed. print $answer;

    Output: (revised after changes)

    C:\test>210085 the core is (so) hot and 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
      Thanks Monks

      I did not think in create another hash for each question

      my %lookup; @lookup{@keys} = @values;

      Some doubts:
      Why concatenate a space to the key?
       my $key = join'',@keys;
      and Why $answer = 'The' . $answer;
      NP1 have 'the'core even it is not in uppercase the first character.

      Thanks this has helped me a lot!!

        Why concatenate a space to the key? my $key = join'',@keys;

        That isn't a space, it's the null string. Ie. Two single quotes, with nothing in between.

        and Why $answer = 'The' . $answer; NP1 have 'the'core even it is not in uppercase the first character.

        That's because I didn't recognise that each /tag applied to everything between it and the preceeding tag. My mistake. I'll amend the code above in a few minutes.


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

      I hope you can help me, yesterday I tried your code as it is and it was ok, but when I use it in with my program where I have my hash of array and my files with questions, the results I got were the following:

      How/WRB1 hot/JJ1 is/VBZ1 the core/NP1 of/IN1 the earth +/NP2 ?/
      ARRAY(0x8152bb0) or

      the values of my hash /NP1/VBZ1(so)/JJ1 and /NP1/IN1/NP2/VBZ1(really)/JJ1 when I changed...
      print "@$answer";
      I know is a problem of dereference of the var, but I have tried the whole night but I am blocked!! , I even read the perlref.

      Thanks for any help

        I would willingly try to help, but you will have to help me by making your question/problem a little clearer.

        The easiest way to do this would be to post (the relevant bits of) your code plus the inputs and failing output. If it is difficult to extract the relevant parts, and too big to post it all, then perhaps you could make the code visible on the net somewhere and post or /msg a url and I will try to take a look.


        Nah! Your thinking of Simon Templar, originally played by Roger Moore and later by Ian Ogilvy
Re: Match key and return value in some order
by gjb (Vicar) on Nov 04, 2002 at 00:16 UTC

    From the look of it, you could populate another hash with the POS/realizations of the question, ie. WRB1 => 'how', JJ1 => 'hot', VBZ1 => 'is', etc and then simply fill out the "template" of the answer sentence, replacing the semi-colon with ', and'.

    Hope this helps, -gjb-