5分以上egrep正規表現

5分以上egrep正規表現

私のテキストファイルには、次の時間形式があります。

       `1` equals one second.
    `5|01` equals five minutes and one seconds.
   `13|01` equals thirteen minutes and one seconds.
`21|12|01` equals 21 hours, 12 minutes, and 1 seconds.

5分より長いエントリをegrepする必要があります。次の正規表現を使用していますが、次の時間を除外しているため機能しません13|00

'[[:space:]0-9][[:space:]0-9][[:space:]|][[:space:]0-9][[:space:]6-9][|][0-9][0-9]'

例は次のとおりです。

 lite on       1
 lite on      01
 lite on    5|22
 lite on   23|14
 lite on 1|14|23

答え1

空白(後で直接埋めることができます)と前の0(もう一度)を無視してください。

[5-9]\|[0-9]+
[1-9][0-9]\|[0-9]+
[0-9]+\|[0-9]+\|[0-9]+

範囲内の時間

[5,10) minutes
[10,99) minutes
1+ hours

それぞれ。

(...|...)したがって、開始と終了に十分な固定がある一致グループに参加してください(したがって、または一致14|59しません1|00|00)。

これは

grep -E 'on +([5-9]\|[0-9]+|[1-9][0-9]\|[0-9]+|[0-9]+\|[0-9]+\|[0-9]+) *$'

秒は3つの正規表現に共通しているため、これを少し単純化できます。

grep -E 'on +([5-9]|[1-9][0-9]|[0-9]+\|[0-9]+)\|[0-9]+ *$'

答え2

これは働きます:

grep -E '( [0-9]{1,2}\|[0-9]{1,2}\|[0-9][1-9] )|( [0-9][0-9]\|[0-9]{2,2} )|( [5-9]\|[0-9][1-9] )|( [6-9]\|[0-9][0-9] )' <file>

デフォルトでは、「でカプセル化され」で区切られた4つのパターンを作成します()|動作は正規表現|と同じです。or

この{1,2}部分は1-2 instances of preceding pattern本当に[0-9]{1,2}意味があります。1-2 instances of 0-9

or次に、構文を使用して、可能なすべての数値の組み合わせの基本的なテストケースを作成します。

答え3

grep正規表現はパターンマッチングには適していますが、値マッチングには適していません。することもできますが、ハンマーをドライバーとして使用します。技術的にはうまくいきますが、乱雑で非効率的です。

だから代わりに:

#!/usr/bin/env perl

use strict;
use warnings;

while (<DATA>) {
    my @numbers = m/(\d+)/g;
    my $seconds = pop(@numbers);
    $seconds += ( pop(@numbers) // 0 ) * 60;  #second digit minutes -> seconds
    $seconds
        += ( pop(@numbers) // 0 ) * 60 * 60;  #third digit, hours  -> seconds;
    print if $seconds > 300;
}

__DATA__
 lite on       1
 lite on      01
 lite on    5|22
 lite on   23|14
 lite on 1|14|23

これは以下を印刷します:

 lite on    5|22
 lite on   23|14
 lite on 1|14|23

次のように単純化できます。

perl -ne 'for ( m/(\d+)/g ) { $t *= 60; $t += $_ }; print if $t > 300;'

ボーナスポイントの場合 - あまり難なく、かなりランダムな検証基準を処理し、いつか別の値を見つけることにした場合、多くの修正は必要ありません。

しかし、上記のタスクは次のように動作します。

  • m/(\d+)/g- を一致として使用することは、g「1つ以上の数値」の繰り返しインスタンスを配列として選択することを意味します。 (@numbersまたは2番目の例のforループ内の自己完結型イテレータと同じです)。
  • この数値チェーンは60を掛けて秒に変換します。 (曜日を追加するとうまくいきません!)
  • 次に、数値が300より大きいかどうかをテストします。これは秒単位で5分です。

関連情報