Como combinar a data em Perl - assumindo que a regex do UNIX é a mesma que a do Perl

0

Quero corresponder datas do formulário

Monday May 26

Minha tentativa de fazer isso é a seguinte:

/(.*day Jan.*|Feb.*|Mar.*|Apr.*|May|Jun.*|Jul.*|Aug.*|Sep.*|Oct.*|Nov.*|Dec.* [1-31])/

O formulário regex no UNIX e no Perl parece ser o mesmo, então é por isso que peço aqui.

    
por Wilhelm Von Lotka 31.05.2014 / 21:19

2 respostas

1

Expressões regulares do Perl e Perl Compatible As Expressões Regulares são ligeiramente diferentes do regex POSIX "básico" ou "estendido" que utilitários como grep implementam. A Wikipedia é provavelmente o melhor lugar para obter uma introdução às diferenças. O suporte a PCRE pode estar disponível em outros lugares além do Perl, como o GNU grep -P .

Para um regex básico:

echo "Monday Feb 23" | grep '^[[:alpha:]]+day (Jan\|Feb\|Mar\|Apr\|May\|Jun\|Jul\|Aug\|Sep\|Oct\|Nov\|Dec)[[:alpha:]]* [1-9][0-9]?$'

Para um regex Perl com grupos de captura nomeados:

$re = qr/
  ^                      # Start of string
  (?<day>[[:alpha:]]+day)  # Match one or more alpha characters before "day". 
  \s+                    # One or more whitespace chars
  (?<month>(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[[:alpha:]]*) # Months
  \s+                    # One or more whitespace chars
  (?<number>\d{1,2})     # 1-2 digits.   
  $                  # End of string. 
/x;

print "match\n" if ( "Thursday May 1" =~ $re );
print "match\n" if ( "Monday February 23" =~ $re );
print "no match\n" if ( "Wednesday May 123" !~ $re );
print "no match\n" if ( "Thursday Blarg 23" !~ $re );
print "no match\n" if ( "Inglebert January 5" !~ $re );

O modificador x após os delímetros // permite o uso de espaço em branco e comentários para que suas expressões regulares sejam mais legíveis.

Uma correspondência bem-sucedida armazenará cada campo em seu próprio grupo de captura, que pode ser acessado por meio do hash da correspondência $+

printf "day [%s] month [%s] day of month [%s]\n", $+{day}, $+{month}, $+{number}

Você pode ficar um pouco mais técnico com a correspondência de números se quiser que ela seja exata.

(?<number>[1-9]|[12][0-9]|3[01])

Se você está chegando a este nível, você deve estar olhando para usar um módulo de análise de data em vez de expressões regulares, pois as datas são muito complexas. Por exemplo, 31 de abril ou fevereiro em geral.

    
por 01.06.2014 / 08:31
0

Sua entrada corresponderá ao seguinte padrão em Perl. Aqui está o oneliner Perl:

perl -e 'if("Monday February 23" =~ /(^.*day (Jan.*|Feb.*|Mar.*|Apr.*|May|Jun.*|Jul.*|Aug.*|Sep.*|Oct.*|Nov.*|Dec.*) [1-31]+)/) {print $1}'
    
por 01.06.2014 / 01:37