Tutorial :Extract values after match a keyword



Question:

I would like to extract values after I match the keyword "coor" multiple times in a string. My code doesn't do that at all. Can anyone help me to fix it please?

My code:

my $str = ;  if ($str =~ /$keyword/)  {    if ($' =~ /\[/) #'# everything after the matched string    {      $str=~ /\(coor\s(\d+)\s(\d+)\)\s\(coor\s(\d+)\s(\d+)\)\s\(coor\s(\d+)\s(\d+)\)\s\(coor\s(\d+)\s(\d+)\)\s/;      {        open( my $file, '>>', $filename );        print {$file} $1, " ";        print {$file} $2, " ";        print {$file} $3, " ";        print {$file} $4, " ";        print {$file} $5, " ";        print {$file} $6, " ";        print {$file} $7, " ";        print {$file} $8, " ";        close( $file );      }    }  }  

This is my input string:

[(beginKey object1 (coor 141 257) (coor 1315 254) (coor 1313 430) (coor 140 420) [] [] []), (beginKey keyword (coor 2035 253) (coor 1315 254) (coor 1313 430) (coor 2034 436) [] [] [])].


Solution:1

Using Perl's \G anchor in scalar context is useful in this case because it continues where a previous //g match left off:

if (/keyword/g) {    my @coor;      while (/\G\s*\(coor (\d+) (\d+)\)/g) {      push @coor => [$1, $2];    }      for (@coor) {      print "@$_\n";    }  }  

With $_ set to your sample input, the code above outputs

2035 253  1315 254  1313 430  2034 436  


Solution:2

You need to escape the special characters in the regex:

(coor (1) (2)) => \(coor (1) (2)\)  

same for /[/ that is a syntax error => /[/

Here is my modified version of your script, the regex is fixed, I split the string on ',' to match the intended keyword and the regex result is tested:

#!/usr/bin/perl  my $keyword = "object1";  my $str = "[(beginKey object1 (coor 141 257) (coor 1315 254) (coor 1313 430) (coor 140 420) [] [] []), (beginKey keyword (coor 2035 253) (coor 1315 254) (coor 1313 430) (coor 2034 436) [] [] [])].";  my @entries=split(',', $str);  foreach my $entry (@entries)  {    if ($entry =~ /$keyword/)    {      my $tomatch=$';      if ($tomatch =~ /\(coor\s(\d+)\s(\d+)\)\s\(coor\s(\d+)\s(\d+)\)\s\(coor\s(\d+)\s(\d+)\)\s\(coor\s(\d+)\s(\d+)\)\s/)      {        print $1," ";        print $2," ";        print $3," ";        print $4," ";        print $5," ";        print $6," ";        print $7," ";        print $8," ";      }      else      {        print "no match !";      }    }  }  

This prints:

141 257 1315 254 1313 430 140 420   


Solution:3

[ is a special character inside a regex, so your second match needs to be against /\[/ to match a literal [.

Your third match has 12 sets of capturing parentheses; I'm guessing you want /coor\s(\d+)\s(\d+)\scoor\s(\d+)\s(\d+)\scoor\s(\d+)\s(\d+)\scoor\s(\d+)\s(\d+)/ instead. You also should check that the match succeeded before using $1, etc.


Solution:4

Hmm, I don't see a problem with your current code.

offtopic: in Qt, QRegExp has a method int MatchedLength() - very easy to see how much of your string was matched.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »