Reputation: 29
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) [] [] [])].
Upvotes: 1
Views: 553
Reputation: 139601
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
Upvotes: 2
Reputation: 1508
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.
Upvotes: 0
Reputation: 26717
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
Upvotes: 1
Reputation: 98398
[ 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.
Upvotes: 0