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

har*_*nic 0 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
}
Run Code Online (Sandbox Code Playgroud)

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

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

/(.*)(\d{2}:\d{2}:\d{2})(.*)(\d{2}:\d{2}:\d{2})?(.*)(\d{2}:\d{2}:\d{2})?(.*)/ 
Run Code Online (Sandbox Code Playgroud)

dax*_*xim 8

g小鸟匹配以重复模式.如果要对它们进行所有操作,请避免使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 此外,您可能希望添加一些lookbehind/lookahead条件来清除误报.例如`(?<!\ d)\ d {2}:\ d {2}:\ d {2}(?!\ d)`所以它不匹配1234:56:7890. (5认同)