0

hh:mm:ss 形式の文字列が 1 回以上含まれています。この正規表現を作成して、グループ化で時間を節約しようとしたので、いくつかの作業を行うことができました。

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
}

問題は、文字列に 1 つ、2 つ、または 3 つの時間が埋め込まれている可能性があることです。この正規表現は、3 つすべてが存在する場合にのみ機能するようです (1 つまたは 2 つではありません)。これを行うためのより良い方法はありますか (そして、「初期化されていない値の使用」警告を回避するために!)?

I tried this, but then it only grabs the last time:

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

1 に答える 1

8

パターンを繰り返すようにg局所的に一致させます。backref 変数を使用してすぐに適切な名前の変数に割り当てるだけの場合は、変数を避けてください。match 演算子は既にキャプチャ バッファの結果を返しています。

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;
    }
}
于 2012-04-22T16:03:30.360 に答える