Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hey!
Given the array element: 19600326.
I want to split this element, so it looks like this: 1960-03-26

Thanks...

Replies are listed 'Best First'.
Re: splitting an array element
by robartes (Priest) on Nov 25, 2002 at 15:07 UTC
    Use substr:
    use strict; my $input="19600326"; substr (((substr ($input,4,0) = '-'),$input),7,0)='-'; print "$input\n"; __END__ 1960-03-26

    CU
    Robartes-

Re: splitting an array element
by broquaint (Abbot) on Nov 25, 2002 at 15:13 UTC
    Or the regex option
    my @ar = qw(foo 19600326 bar); $ar[1] =~ s{^(\d{4})(\d{2})(\d{2})\z}($1-$2-$3); print $ar[1], $/; __output__ 1960-03-26

    HTH

    _________
    broquaint

Re: splitting an array element
by Zaxo (Archbishop) on Nov 25, 2002 at 15:25 UTC

    TIMTOWTDI:

    my $date = '19600326'; my $first = join '-', unpack 'a4 a2 a2', $date; my $second = sprintf '%s-%s-%s', unpack 'a4 a2 a2', $date;

    After Compline,
    Zaxo

Re: splitting an array element
by impossiblerobot (Deacon) on Nov 25, 2002 at 15:31 UTC
    When I think of fixed-length fields, I always think of unpack:
    my $data = '19600326'; print join('-', unpack('A4A2A2', $data));
    or
    my $data = '19600326'; printf ('%s-%s-%s', unpack('A4A2A2', $data));

    Update: Ack! Zaxo beat me to it by a couple of minutes. :-)


    Impossible Robot
Re: splitting an array element
by jmcnamara (Monsignor) on Nov 25, 2002 at 15:17 UTC

    Here is another way to do it:
    my $date = '19600326'; my $newdate = join '-', $date =~ /(....)(..)(..)/;

    --
    John.

Re: splitting an array element
by AcidHawk (Vicar) on Nov 25, 2002 at 15:07 UTC

    Is it always in this (YYYYMMDD) format..? This will work..

    #! perl use strict; my $s = "19600623"; my $yy = substr($s, 0, 4); my $mm = substr($s, 4, 2); my $dd = substr($s, 6, 2); print "$yy-$mm-$dd\n";

    Prints out 1960-06-23

    Update: A little slow when I checked again..;)

    -----
    Of all the things I've lost in my life, its my mind I miss the most.
Re: splitting an array element
by fruiture (Curate) on Nov 25, 2002 at 15:45 UTC

    Whene there are so many WTDI, a Benchmark may be appropriate to chose:

    my $olddate = '20020131'; MyBenchmark::benchmark( $ARGV[0],[ ['regexp \d{}' => sub { my $new; $olddate =~ m/^(\d{4})(\d{2})(\d{2})$/ and $new = "$1-$2-$3"; $new }], ['regexp ..' => sub { my $new; my @p = $olddate =~ /^(....)(..)(..)$/; $new = join '-',@p; $new }], ['s/// \d{}' => sub { my $new = $olddate; $new =~ s/^(\d{4})(\d{2})(\d{2})$/$1-$2-$3/; $new }], ['substr' => sub { my $new = $olddate; substr (((substr ($new,4,0) = '-'),$new),7,0)='-'; $new }], ['join unpack' => sub { my $new; $new = join '-', unpack 'a4 a2 a2', $olddate; $new }], ['sprintf unpack' => sub { my $new; $new = sprintf '%s-%s-%s', unpack 'a4 a2 a2', $olddate +; $new }], ], '2002-01-31' #expected output );

    Note that MyBenchmark::benchmark is just a function i've written that executes all subs beforehand and compares their results with an expected value. The benchmark itself is done via Benchmark::cmpthese.

    join unpack is fastest for me, sprintf unpack is next.

    --
    http://fruiture.de
      Hi,
      I tried to optimize the substr solution a little.
      Now it outperforms join unpack about 70%!
      ['substr faster' => sub { my $new = $olddate; substr($new, 0, 4, substr($new,0,4)."-"); substr($new, 0, 7, substr($new,0,7)."-"); $new }],
      Greetings
      MP
Re: splitting an array element
by rdfield (Priest) on Nov 25, 2002 at 15:15 UTC
    It wouldn't be the Monestary without a regexp solution:
    $a = "19600326"; $a =~ s/(\d{4})(\d{2})(\d{2})/$1-$2-$3/; print "$a\n";

    rdfield

Re: splitting an array element
by Mr. Muskrat (Canon) on Nov 25, 2002 at 16:09 UTC

    In the spirit of TIMTOWTDOI...

    #!/usr/bin/perl use strict; use warnings; my @input=<DATA>; for my $input (@input) { chomp $input; my @characters=split//,$input; my $output; for my $i (0..$#characters) { $output .= "-" if ($i == 4 || $i == 6); $output .= $characters[$i]; } print $output,$/; } __END__ 19600326 19720309 19730303 19921122 19931120 19960629

Re: splitting an array element
by Chief of Chaos (Friar) on Nov 25, 2002 at 15:15 UTC
    Hi,
    a map solution...
    #!/usr/local/bin/perl -w use strict; my $olddate = "20020911"; my $newdate; map { /([\d]{4})([\d]{2})([\d]{2})/; $newdate= "$1-$2-$3"; } $olddate; print $newdate."\n";

      map in void context is bad. In your case, it's really useless...

      $olddate =~ /(\d{4})(\d{2})(\d{2})/ and $newdate = "$1-$2-$3";
      --
      http://fruiture.de