匹配关键字后提取值

时间:2009-06-21 20:05:56

标签: regex perl

我希望在字符串中多次匹配关键字“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) [] [] [])].

4 个答案:

答案 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() - 很容易看出你的字符串有多少匹配。