Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing delimiters from a date/time string

I want to take this

Code:
2010-12-21 20:00:00

and make it look like this:

Code:
20101221200000

This is the last thing I tried

Code:
#!/usr/bin/perl  -w
use strict;
my ($teststring) = '2010-12-21 20:00:00';
my $result =  " ";
print "$teststring\n";
$teststring =~ "/(d\{4\})(d\{3\})(d\{3\})(d\{3\})(d\{3\})(d\{3\})/$result";
        { 
    print "$_\n";
    print "$result\n";
        print "$teststring\n";
    }

And it produced this:

Code:
nathan@debian:~/Desktop$ ./ptest
2010-12-21 20:00:00
Use of uninitialized value $_ in concatenation (.) or string at ./ptest line 8.


2010-12-21 20:00:00
nathan@debian:~/Desktop$

-Thanks

like image 917
Nate the Noob Avatar asked Dec 21 '22 20:12

Nate the Noob


1 Answers

First, here is the problem with your code:

$teststring =~ "/(d\{4\})(d\{3\})(d\{3\})(d\{3\})(d\{3\})(d\{3\})/$result";

You want to use =~ with the substitution operator s///. That is, the right hand side should not be a plain string, but s/pattern/replacement/.

In the pattern part, \d would denote a digit. However, \d includes all sorts characters that are in the Unicode digit class, so it is safer to use the character class [0-9] if that's what you want to match against. [0-9]{4} would mean match characters 0 through 9 four times. Note that you should not escape the curly brackets { and }.

The parentheses ( and ) define capture groups. In the replacement part, you want to keep the stuff you captured, and ignore the stuff you did not.

In addition, I am assuming these timestamps occur in other input, and you do not want to accidentally replace stuff you did not mean to (by blindly removing all non-digits).

Below, I use the /x modifier for the s/// operator so I can format the pattern more clearly using white-space.

#!/usr/bin/perl

use strict; use warnings;

while ( <DATA> ) {
    s{
        ^
        ([0-9]{4})-
        ([0-9]{2})-
        ([0-9]{2})[ ]
        ([0-9]{2}):
        ([0-9]{2}):
        ([0-9]{2})
    }{$1$2$3$4$5$6}x;
    print;
}

__DATA__
Code:
2010-12-21 20:00:00

or, using named capture groups introduced in 5.10 can make the whole thing slightly more readable:

#!/usr/bin/perl

use 5.010;

while ( <DATA> ) {
    s{
        ^
        ( ?<year>  [0-9]{4} ) -
        ( ?<month> [0-9]{2} ) -
        ( ?<day>   [0-9]{2} ) [ ]
        ( ?<hour>  [0-9]{2} ) :
        ( ?<min>   [0-9]{2} ) :
        ( ?<sec>   [0-9]{2} )
    }
    {
        local $";
        "@+{qw(year month day hour min sec)}"
    }ex;
    print;
}

__DATA__
Code:
2010-12-21 20:00:00
like image 55
Sinan Ünür Avatar answered Dec 31 '22 19:12

Sinan Ünür