私のテキストファイルには、次の時間形式があります。
`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分です。