我正在执行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”为$小时。
如果我出错了,请帮助我。谢谢。
答案 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;
......至少应该返回你期待的数字。