我希望在字符串中多次匹配关键字“coor”后提取值。我的代码完全不这样做。有人可以帮我解决一下吗?
我的代码:
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 );
}
}
}
这是我的输入字符串:
[(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) [] [] [])].
答案 0 :(得分:2)
在这种情况下,在标量上下文中使用Perl的\G
锚点非常有用,因为它会在前一个//g
匹配停止的地方继续:
if (/keyword/g) {
my @coor;
while (/\G\s*\(coor (\d+) (\d+)\)/g) {
push @coor => [$1, $2];
}
for (@coor) {
print "@$_\n";
}
}
将$_
设置为您的示例输入,上面的代码输出
2035 253
1315 254
1313 430
2034 436
答案 1 :(得分:1)
你需要转义正则表达式中的特殊字符:
(coor (1) (2)) => \(coor (1) (2)\)
/ / [/即语法错误=> / [/
这是我的脚本的修改版本,正则表达式是固定的,我将字符串拆分为','以匹配目标关键字并测试正则表达式结果:
#!/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 !";
}
}
}
打印:
141 257 1315 254 1313 430 140 420
答案 2 :(得分:0)
[是正则表达式中的特殊字符,因此您的第二个匹配需要与/\[/
匹配以匹配文字[。
你的第三场比赛有12套捕捉括号;我猜你想要/coor\s(\d+)\s(\d+)\scoor\s(\d+)\s(\d+)\scoor\s(\d+)\s(\d+)\scoor\s(\d+)\s(\d+)/
。在使用$ 1等之前,您还应该检查匹配是否成功。
答案 3 :(得分:0)
嗯,我发现你当前的代码没有问题。
offtopic:在Qt中,QRegExp有一个方法int MatchedLength() - 很容易看出你的字符串有多少匹配。