Link to home
Start Free TrialLog in
Avatar of trevor1940
trevor1940

asked on

Perl: Capitalize First Letter of Each Word in a file name

Hi I'm trying to Capitalize First Letter of Each Word in a file name but keep the file extension lower case
I'm already removing the rubbish from the  name and I would like the results to look like this

"The.Best.TV.Show.S01E01.720p.Mkv"

my $Ext = "\.mp4|\.mkv|\.avi|\.srt";
while (my $file = <DATA>){

    my $new =  $file;
    $new =~ s/^(.+?(720|1080)p).+($Ext)$/$1$3/i;
    $new =~ s/\b(\w).*(?<=$Ext)/\U$1/g;
    print "new = $new\n";
    
}

__DATA__
the.best.TV.show.s01e01.720p.crap.here.mkv
the.best.TV.show.s01e02.1080p.mp4
the.best.TV.show.s01e03.720p.mpg
the.best.TV.show.s01e04.720p.avi
the.best.tv.show.jpg

Open in new window

Avatar of tel2
tel2
Flag of New Zealand image

How's this, Trev?:
    $new =~ s/(?<![A-Za-z])([a-z])/uc$1/ge;
or more concisely if you have Perl 5.10.0 or later:
    $new =~ s/[^A-Za-z]\K([a-z])/uc$1/ge;

Here's a demo of the latter regex from the Linux command line:
    echo the.best.TV.show.s01e03.720p.mpg | perl -pe 's/[^A-Za-z]\K([a-z])/uc$1/ge'
The.Best.TV.Show.S01E03.720P.Mpg

You could alternatively use this slightly more concise version:
      $new =~ s/[^A-Za-z]\K[a-z]/uc$&/ge;
but I think it may be slightly less efficient, performance wise.
An alternative non-substitution-regex version would be:
my @arr = map { /^s\d+e\d+$/ ? uc($_) : ucfirst $_ } split /\./, $file; # ucfirst each word (special case sXXeYY)
$arr[-1] = lc $arr[-1]; # change extension to lower-case
my $new = join '.', @arr; # rejoin string with fixed capitalization

Open in new window

SOLUTION
Avatar of tel2
tel2
Flag of New Zealand image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of trevor1940
trevor1940

ASKER

Thanx for your help

Both soltions work hence dividing the points

I was thinking I might of needed to use fileparse to split the file name into parts


[code]
    my($name, $foo, $ext) = fileparse($file, qr/\.[^.]*/);
    print "namme $name, $ext\n";
[/code]