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

Hello all

I'm trying to strip off offensive characters from filename with the below snippet written long back (not by me) and is not doing what exact I want.

use strict; use warnings; print cleanfilename('abcdefghijklmnopqrstuvwxyz.xml'); sub cleanfilename { my ($ans) = @_; $ans =~ y/\/\\[]{}()?*#$^&@*;''""``<>%|//d; $ans =~ y/[[:space:][:cntrl:]]//d; return $ans; }

Output

bdfghijkmoquvwxyz.xm

Replies are listed 'Best First'.
Re: Strip filename
by almut (Canon) on Dec 22, 2009 at 09:01 UTC
    $ans =~ y/[[:space:][:cntrl:]]//d;

    As the docs say (--> 'Note that "tr" does not do regular expression character classes such as "\d" or "[:lower:]"'), character classes cannot be used with tr/// (which is the same as y///).  Use regex substitution (s///) instead.

Re: Strip filename
by Ratazong (Monsignor) on Dec 22, 2009 at 08:57 UTC
    you are "escaping" / and \ (by using \/ \\) ... but what about ( ) $ ? ..... - they all have special meanings!
    Try escaping them, too!
    HTH Rata
      Actual culprit is below line which is replacing some of the characters like 'l' or 'c' with null values. Is there any alternative for this...
      $ans =~ y/[[:space:][:cntrl:]]//d;
        Is there any alternative for this

        Yes:  $ans =~ s/[[:space:][:cntrl:]]//g;

Re: Strip filename
by Anonymous Monk on Dec 22, 2009 at 18:04 UTC
    Another idea is specify only allowed characters, like ascii letters and numbers dash and underscore
    s![^abcdefghijklmnopqrstuvwxyz0123456789_\-]!!gi
    or create sha1 hash of the file and use that as the filename
    $ perl -MDigest -le " $sha256 = Digest->new(q!SHA-256!); $sha256->add +file( *STDIN ); print $sha256->hexdigest " < test a505e6720df306ab46a6b24c458b8b77b60bffa18d831f4796ba1b736bb44c6c