2012-01-05 21 views
5

Me gustaría volver a organizar una marca de tiempo con una Perl regex con el menor código posible. El formato original de la marca de tiempo es el siguiente:Reordenando una marca de tiempo con una regex Perl

2011/12/29 20:19:45 

Todo lo que tiene que hacer es convertirlo de manera que el año en la parte delantera en lugar viene después del mes/fecha de la siguiente manera:

12/29/2011 20:19:45 

Pude lograr esto con las 3 líneas de código a continuación. Me pregunto si hay una manera de hacer esto con menos código. En particular, traté de eliminar la línea media, ahorrando $ 1 en una variable intermedia y especificando $ 1 desde la primera sustitución directamente en la expresión regular para la segunda sustitución, pero esto dio como resultado el error: "Uso de valor no inicializado $ 1 en la concatenación (.) o cadena. "

Si no puede deshacerse de la segunda línea, entonces parece que tampoco se puede acceder a una línea.

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

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

Si va a modificar esta pregunta, por favor diga por qué. Esa es la manera SO, y si eres alguien de comp.lang.perl.misc que he ofendido, lo siento, pero tenemos una cultura diferente aquí, y si no te gusta, solo vuelve a clpm ¿O no ves la ironía de "Hay más de una forma de hacerlo" de Perl, pero clpm "Solo hay una manera de usar" –

+0

+1 en el comentario de George. Por favor, no baje el mod sin una explicación. Eso no es útil para nadie. – AWT

Respuesta

5

A continuación se van:

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

Tenga en cuenta que la expresión anterior marcas de tiempo de espera que tiene exactamente 2 dígitos para el mes y día y 4 dígitos para el año. Pero puede que sea aún más corto aún más fiable:

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

Ésta se encargará de marcas de tiempo como 12/01/98 12:34:56 correctamente.

+0

Gracias por su respuesta expandida incluyendo la explicación y la mejora sobre mis "palillos de dientes inclinados" –

+0

En cualquier momento. Por cierto, puedes hacer que la expresión regular sea aún más corta al combinar el día y el mes juntos: 's |^(\ d +)/(\ d +/\ d +) (. +) $ | $ 2/$ 1 $ 3 |' :) –

+0

Gracias y por favor considere modificar la pregunta si lo encuentra interesante. Aparentemente algunos trolls de comp.lang.perl.misc van a modificar todas las preguntas de Perl que hago aquí. –

1

Usando Referencias hacia atrás se puede obtener el formato deseado -

[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' etc. mejor escrito como' $ 3'. – TLP

+1

Es cierto ... realmente no sé 'perl' solo usó sus capacidades' sed'. Se actualizará la respuesta, ya que se ve mejor y gracias por los comentarios. :) –

+0

De nada. – TLP

0

Para mayor manipulación marca de tiempo genérico que posiblemente desea ida y vuelta a través de strptime/strftime. En este caso, es solo un reordenamiento de campo, pero para casos más complejos, como convertir números de mes en nombres, se requerirá 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 
Cuestiones relacionadas