Não use grep
. Expressões regulares são para padrões de correspondência, mas são realmente horríveis para valores correspondentes. Você provavelmente pode fazer isso, mas você está usando um martelo como uma chave de fenda. Tecnicamente funciona, mas é confuso e ineficiente.
Então, ao invés disso:
#!/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
Isto imprime:
lite on 5|22
lite on 23|14
lite on 1|14|23
Você pode fazer isso com uma linha:
perl -ne 'for ( m/(\d+)/g ) { $t *= 60; $t += $_ }; print if $t > 300;'
Para pontos de bônus - isso lida com critérios de validação bastante arbitrários, sem muita dificuldade, e não requer nem de longe o máximo possível se você decidir ganhar um valor diferente um dia.
Mas o texto acima funciona de:
- use
m/(\d+)/g
- como uma correspondência g
, significa que ele seleciona instâncias repetidas de "um ou mais dígitos" em uma matriz. ( @numbers
ou apenas como um iterador independente no loop for no segundo exemplo).
- converte essa cadeia de dígitos em segundos, multiplicando por 60. (Isso não funcionará tão bem se você adicionar dias a ele!)
- E depois testa esse número por ser maior que 300 - o que é 5 minutos em segundos.