2012-01-05 6 views
5

Mi piacerebbe riorganizzare un timestamp con un'espressione regolare Perl con il minor numero possibile di codice. Il formato originale della data e ora è la seguente:Riorganizzazione di un timestamp con un'espressione regolare Perl

2011/12/29 20:19:45 

Tutto quello che devi fare è convertirlo in modo che l'anno nella parte anteriore invece viene dopo il mese/data come segue:

12/29/2011 20:19:45 

Sono stato in grado di raggiungere questo risultato con le 3 linee di codice qui sotto. Mi sto solo chiedendo se c'è un modo per farlo con meno codice. In particolare, ho cercato di eliminare la linea di mezzo salvando $ 1 in una variabile intermedia e specificando $ 1 dalla prima sostituzione direttamente nella regex per la seconda sostituzione, ma questo ha provocato l'errore: "Uso del valore non inizializzato $ 1 nella concatenazione (.) o stringa. "

Se la seconda linea non può essere eliminata, sembra che non si possa ottenere neanche una riga?

#my $ts = '2011/12/29 20:19:45'; #input to a subroutine 

$ts =~ s/^(\d{4})\///; 
my $year = $1; 
$ts =~ s/ /\/$year /; 
+0

Se hai intenzione di scollegare questa domanda, ti preghiamo di spiegarne il motivo. Questo è il modo SO, e se sei qualcuno di comp.lang.perl.misc che ho offeso, mi dispiace, ma qui abbiamo una cultura diversa, e se non ti piace, torna a clpm. Oppure non vedi l'ironia di Perl "C'è più di un modo per farlo", ma clpm "C'è solo un modo per usenet" –

+0

+1 sul commento di George. Si prega di non down-mod senza una spiegazione. Questo non è utile a nessuno. – AWT

risposta

5

Qui sono andate:

$ts =~ s|^(\d{4})/(\d{2})/(\d{2})(.+)$|$2/$3/$1$4|; 

Si prega di notare che l'espressione di cui sopra si aspetta che i timestamp avere esattamente 2 cifre per mesi e giorni e 4 cifre per anni. Ma si può rendere ancora più breve ancora più affidabile:

$ts =~ s|^(\d+)/(\d+)/(\d+)(.+)$|$2/$3/$1$4|; 

Questo consente di gestire timestamp come 1/12/98 12:34:56 correttamente.

+0

Grazie per la tua risposta estesa, comprese spiegazioni e miglioramenti sui miei "stuzzicadenti appoggiati" –

+0

In qualsiasi momento. A proposito, è possibile rendere ancora più breve l'espressione regolare combinando giorno e mese insieme: 's |^(\ d +)/(\ d +/\ d +) (. +) $ | $ 2/$ 1 $ 3 |' :) –

+0

Grazie e per favore considera di modificare la domanda stessa se la trovi interessante. A quanto pare alcuni troll di comp.lang.perl.misc stanno andando in down-mod ogni domanda Perl che chiedo qui. –

1

Utilizzando Torna Riferimenti È possibile ottenere la formattazione desiderata -

[jaypal:~/Temp] echo "2011/12/29 20:19:45" | 
perl -pe '[email protected]([0-9]{4})/([0-9]{2})/([0-9]{2})@$3/$1/[email protected]' 
29/2011/12 20:19:45 
+2

'\ 3' ecc. Scritto meglio come' $ 3'. – TLP

+1

Vero ... non so davvero che 'perl 'abbia usato le sue capacità' sed'. Aggiornerà la risposta come sembra migliore e grazie per il feedback. :) –

+0

Prego. – TLP

0

Per ulteriori manipolazione timestamp generico Probabilmente vuoi andata e ritorno in strptime/strftime. In questo caso è solo il riordino in campo, ma per i casi più complessi come l'inserimento dei numeri dei mesi in nomi, sarà richiesto il numero strftime.

my @t = strptime "2011/12/29 20:19:45", "%Y/%m/%d %H:%M:%S"; 

say strftime "%d/%m/%Y %H:%M:%S", @t; # 29/12/2011 20:19:45 
say strftime "%d %b %Y, %H:%M:%S", @t; # 29 December 2011, 20:19:45 
Problemi correlati