2013-03-20 9 views
5

Voglio definire una costante regexp nel mio script in alto e usarla in seguito per controllare il formato della stringa di data.Come posso definire un motivo regexp come costante in Perl?

mia stringa data verrà definita come

$ a = "2013/03/20 11: 09: 30,788";

ma non è riuscito. come devo fare?

use strict; 
use warnings; 


use constant REGEXP1 => "/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/"; 

$a="2013-03-20 11:09:30.788"; 
if(not $a=~&REGEXP1){ 
     print "not" 

}else{ 
     print "yes" 

} 
print "\n"; 

risposta

3

Quale versione di Perl stai utilizzando? Funziona per me a 5.8.8 (ma non 5.004) se si cambia in questo modo:

use constant REGEXP1 => qr/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/; 
9

In primo luogo, diamo un'occhiata a "/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/"; Se tu avessi avvertimenti su, dovreste aver ottenuto:

Unrecognized escape \d passed through at C:\temp\jj.pl line 7. 
Unrecognized escape \D passed through at C:\temp\jj.pl line 7. 
Unrecognized escape \d passed through at C:\temp\jj.pl line 7. 
…

Se si stampa il valore di REGEXP1, si otterrà /^d{4}Dd{2}Dd{2}Dd{2}Dd{2}Dd{2}Dd{3} (* attendere, cosa è successo a $/?). Chiaramente, quello non sembra il modello che volevi.

Ora è possibile digitare "/^\\d{4}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{3}\$/" e quindi interpolare quella stringa in un modello, ma è troppo lavoro. Invece, è possibile definire la costante utilizzando il regexp quote operator, qr:

#!/usr/bin/env perl 

use 5.012; 
use strict; 
use warnings; 

use constant REGEXP1 => qr/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/; 

my $s = "2013-03-20 11:09:30.788"; 

say $s =~ REGEXP1 ? 'yes' : 'no'; 

C'è un altro Gotcha: \d e \D corrisponderà più di un semplice [0-9] e [^0-9], rispettivamente. Così, invece, si potrebbe scrivere il vostro modello come:

use constant REGEXP1 => qr{ 
    \A 
    (?<year> [0-9]{4}) - 
    (?<month> [0-9]{2}) - 
    (?<day> [0-9]{2}) [ ] 
    (?<hour> [0-9]{2}) : 
    (?<min> [0-9]{2}) : 
    (?<sec> [0-9]{2}) [.] 
    (?<msec> [0-9]{3}) 
    \z 
}x; 

Ma, si sta ancora a sinistra con la questione se questi valori sono significativi. Se ciò è importante, è possibile utilizzare DateTime::Format::Strptime.

#!/usr/bin/env perl 

use 5.012; 
use strict; 
use warnings; 

use DateTime::Format::Strptime; 

my $s = "2013-03-20 11:09:30.788"; 

my $strp = DateTime::Format::Strptime->new(
    pattern => '%Y-%m-%d %H:%M:%S.%3N', 
    on_error => 'croak', 
); 

my $dt = $strp->parse_datetime($s); 
say $strp->format_datetime($dt); 
+0

Cosa corrispondono '\ d' e' \ D' al di fuori di '[0-9]'? – RickF

+1

Vedere "Cifre" in [perldoc perlrecharclass] (http://perldoc.perl.org/perlrecharclass.html). * Ciò significa che, a meno che il modificatore '/ a' sia in effetto' \ d', non solo corrisponda alle cifre ''0' - '9'', ma anche arabo, Devanagari e cifre da altre lingue. Ciò potrebbe causare confusione e alcuni problemi di sicurezza. * –

Problemi correlati