Perforce命令正则表达式

时间:2015-03-16 18:50:13

标签: regex perl

我正在执行perforce命令行,如下所示:

2806  I deep  sd_bordeaux 117:02:40 IDLE none
2807  I deep  sd_bordeaux 17:02:40  IDLE none
2808  I deep  sd_coddeaux 117:02:40 IDLE all
2809  I rahul sd_coddeaux 117:02:40 IDLE all

我编写了以下代码来运行命令以获取$ command中的上述列表并将其存储在数组@lines中并使用正则表达式来获取指定的条件。但我没有得到预期的结果。

my $command = qx |p4 monitor show -ale|;
my $kill_id;
my @lines = split("\n", $command);
for my $line (@lines){
    next if not $line =~ /(\d+)\s+/;
    my $id = $1;
    if ($line =~ /sd_bordeaux\s+(\d+):\d+:\d+\s+/ and $line =~ /IDLE\s+none$/){
        my $hours = $1;
        print "$hours";
        print "\n";
    }

}

我收到错误

Use of uninitialized value $hours in string at ./p4.pl

我有兴趣将数字“2806”和“2807”作为$ id和第一个数字“117”& “17”为$小时。

如果我出错了,请帮助我。谢谢。

2 个答案:

答案 0 :(得分:2)

$1包含第一次捕获最近成功的正则表达式匹配所匹配的内容。

当您收到错误消息时,最近的成功匹配针对的是/IDLE\s+none$/,其中不包含任何捕获。

以下内容相同:

if ($line =~ /sd_bordeaux\s+(\d+):\d+:\d+\s+/) {
    my $hours = $1;
    if ($line =~ /IDLE\s+none$/) {
        print "$hours\n";
    }
}

但看起来您只需要以下内容:

if ($line =~ /sd_bordeaux\s+(\d+):\d+:\d+\s+IDLE\s+none$/) {
    my $hours = $1;
    print "$hours\n";
}

这解释了问题以及如何解决问题,但Garry提供的alternative approach更具可读性。

答案 1 :(得分:1)

有了这样的数据,为什么要使用正则表达式?

for my $line (@lines) {
  my @elems = split /\s+/, $line;
  next unless $elems[3] eq "sd_bordeaux";
  next unless $elems[-2] eq "IDLE";
  next unless $elems[-1] eq "none";
  print "$elems[0]\n";
}

即使你的正则表达式有所回应也没有兴趣,它也不会给你280x你期待的东西;它会给你,例如117:02:40的117部分

如果由于某种原因它必须是一个正则表达式,你可以用..

if $line =~ /^(\d+)\s+.s*sd_bordeaux\s+(\d+).*IDLE\snone$/ {
  my $id = $1;
  my $hours = $2;

......至少应该返回你期待的数字。