13

The below program is to rearrange a string. For line 8, I am trying to store the results of a regex into a new variable $newdate, but when $newdate is printed in line 9, it only displays a 1. How can I change my code so that $newdate will store the $date value from the regex operation?

1 #!/usr/bin/perl
2 
3 # This program changes the date format from mm/dd/yyyy to yyyy,mm,dd
4 
5 $date = '21/11/2011';
6 print "Current: $date\n";
7
8 $newdate = $date =~ s/(..)\/(..)\/(....)/$3,$2,$1/;
9 print "New: $newdate\n";
rid
  • 61,078
  • 31
  • 152
  • 193
kurotsuki
  • 4,357
  • 8
  • 25
  • 28

4 Answers4

17

You could also do it like this :

my $date = '21/11/2011';
print "Current: $date\n";
my $newdate;
($newdate = $date) =~ s/(..)\/(..)\/(....)/$3,$2,$1/;
print $newdate;
FailedDev
  • 26,680
  • 9
  • 53
  • 73
13

Since Perl 5.13.2, non-destructive substitution can be specified through the s///r modifier so a copy of the post-substitution string is assigned instead of the number of matches. It also prevents the original string from being modified, which means the two assignments have the same behavior:

( my $new_date = $date ) =~ s<(..)/(..)/(....)><$3,$2,$1>; # Pre-5.13.2

  my $new_date = $date =~ s<(..)/(..)/(....)><$3,$2,$1>r;  # Post-5.13.2

From perldoc perl5132delta:

Non-destructive substitution

The substitution operator now supports a /r option that copies the input variable, carries out the substitution on the copy and returns the result. The original remains unmodified.

my $old = 'cat';
my $new = $old =~ s/cat/dog/r;
# $old is 'cat' and $new is 'dog'
Zaid
  • 36,680
  • 16
  • 86
  • 155
4

The =~ operator will return the number of changes made when doing substitution, and unless you're doing it globally, it will always return 1 or 0. Additionally, the substitutions are made in place, so if your aim is not to modify $date, you don't want to substitute.

Try:

$date =~ m/(..)\/(..)\/(....)/;
$newdate = "$3,$2,$1";
Wooble
  • 87,717
  • 12
  • 108
  • 131
1

In the spirit of TIMTOWTDI:

my $date = '21/11/2011';

my $newdate = join ",", reverse split m#/#, $date;

This just happens to work because you want the reverse order on the numbers. You could also do this:

my $newdate = join ",", ( split m#/#, $date )[2,1,0];

Yet another way:

my $newdate = join ",", reverse ( $date =~ /(\d+)/g );

Also: Why use strict and warnings?

Community
  • 1
  • 1
TLP
  • 66,756
  • 10
  • 92
  • 149