在Perl中的字符串中匹配并保存一个或多个实例

时间:2012-04-22 15:37:34

标签: regex perl

我有一个或多次以hh:mm:ss格式的字符串。我创建了这个正则表达式来尝试使用分组来保存时间,这样我就可以做一些工作了:

if ( $s =~ /(.*)(\d{2}:\d{2}:\d{2})(.*)(\d{2}:\d{2}:\d{2})(.*)(\d{2}:\d{2}:\d{2})(.*)/ )
{
  my @t = ( $2, $5, $8 );
  # loop through times and do stuff
}
else
{
  # no match found
}

问题是字符串可能有一个,两个或三个嵌入时间 - 而且这个正则表达式似乎仅在所有三个都存在时才有效(不是一个或两个)。有没有更好的方法来做到这一点(并避免任何“使用未初始化的值”警告!)?

我尝试了这个,但之后它只抓住了最后一次:

/(.*)(\d{2}:\d{2}:\d{2})(.*)(\d{2}:\d{2}:\d{2})?(.*)(\d{2}:\d{2}:\d{2})?(.*)/ 

1 个答案:

答案 0 :(得分:8)

匹配globally以重复模式。如果要对它们进行所有操作,请避免使用backref变量将它们立即分配给一些更好的命名变量;匹配运算符已经返回捕获缓冲区结果。

use Data::Dumper qw(Dumper);
my $timestamp = qr'
    (?<!\d)            # avoid digits before
    \d{2}:\d{2}:\d{2}  # hh:mm:ss
    (?!\d)             # avoid digits after
'x;

for my $s (qw(
    foo18:00:00bar18:00:00baz18:00:00quux
    foo18:00:00bar18:00:00baz
    foo18:00:00bar
)) {
    if (my @t = $s =~ /($timestamp)/g) {
        print Dumper \@t;
    }
}