在perl中匹配字符串

时间:2013-12-18 12:14:18

标签: regex perl

if ($time =~ /^[01]?\d\./) {       # time is 0-9 seconds or 10-19 seconds
    $status = "OK";
}
elsif ($time =~ /^(2\d|30)\./) {   # time is 20-30 seconds
    $status = "WARNING";
}
else {                             # any other time is critical
    $status = "CRITICAL";
}

在上面的代码中我有一些阈值。 我需要的是将0-10更改为OK,将10-30更改为WARNING,其他所有内容都为CRITICAL。 该字符串的时间类似于1.01.1113.512:13.52

2 个答案:

答案 0 :(得分:2)

经常说当你有一把锤子时,每个问题看起来都像一个钉子,在这种情况下也是如此,你使用模式匹配进行简单的数值比较。

为什么不将这些作为数字进行评估?它的可维护性要高得多。

$status = "CRITICAL";
if ($time =~ /^(\d+)\./) { # Starts with seconds
    $seconds = $1;
    $status = "WARNING" if ($seconds <= 30);
    $status = "OK" if ($seconds <= 10);
    # If status is OK, print a message
    print "$status: Execution took $seconds seconds" if ($status eq "OK");
} else {
    # Time doesn't start with seconds, so status is critical
}

现在,将来,任何想要更改阈值的人都可以修改简单数值比较器中的数字。

答案 1 :(得分:2)

您正在使用正则表达式来处理不适合的内容。

会更好
  1. 从字符串
  2. 中提取数字
  3. 使用数值比较运算符指定级别
  4. 这可能如下所示:

    sub level {
      my ($time) = @_;
      $time =~ /\A (?: (?: (?<hours>[0-9]+): )? (?<minutes>[0-9]+): )?  (?<seconds>[0-9]+) [.]/x
        or die "Can't match seconds";
      my $seconds = $+{seconds} + 60 * ($+{minutes} + 60*$+{hours});
    
      my $warning  = 20;
      my $critical = 31;
    
      my $status = ($seconds < $warning ) ? "OK"
                 : ($seconds < $critical) ? "WARNING"
                 :                          "CRITICAL";
      return $status;
    }
    
    use Test::More tests => 8;
    
    is level("1.0"),     "OK";
    is level("1.11"),    "OK";
    is level("13.51"),   "OK";
    is level("2:13.52"), "CRITICAL";
    is level("26.0"),    "WARNING";
    is level("26.11"),   "WARNING";
    is level("2:26.52"), "CRITICAL";
    is level("0:26.52"), "WARNING";