开发者

Perl Regex Output only characters that can be used as unix filename

I wrote a basic mp3 organizing script for myself. I have the line: $outname = "/home/jebsky/safehouse/music/mp3/" . $inital . "/" . $artist . "/" . $ye开发者_运维技巧ar ." - ". $album . "/" . $track ." - ". $artist ." - ". $title . ".mp3";

I want a regex to change $outname so that any non safe for filename characters get replaced by an underscore


If any of your components include "/", you really want to do the substitution on them before assembling them into $outname.

Which characters are safe can vary from one operating system and/or filesystem to another. Many filesystems have no problem with any characters other than "/" and nul. You're probably better off deciding which characters you want to keep, for other reasons than what your filesystem allows.

The following keeps only letters and digits, replacing sequences of other characters with _:

for ( $initial, $artist, $year, $album, $track, $title ) {
    s/[^A-Za-z0-9]+/_/g;
}


One quick way to escape all non-alphabetic characters in a string is to use the \Q and \U operators, as in:

# assuming $outname already contains the required path and
# globally "unescaping" file chars / and .

($outname = "\Q$outname\U") =~ s/\\([\/\.])/$1/g;

One thing to consider is that long run-on string cats like you have tend to both be hard to read and maintain. A better way of representing this operation might be to break it up into logical units, like:

my $basename   = '/home/jebsky/safehouse/music/mp3';
my $dirpath    = "${basename}/${initial}/${artist}/${year}-${album}/";
my $filename   = "${track}-${artist}-${title}.mp3";

$outname       = "${dirpath}/${filename}";

Within strings, representing a variable as "${varname}" assures that the character that follows the varname cannot interfere with it and is usually a good idea even if the next character after the var isn't alphanumeric because it clearly marks variables within the string.

Finally, I think it's a good idea to get away from using '"' and '\'' as string delimiters since they require quoting if the string contains the delimiter.

Use the qq// and q// delimiters (replacing the / with a char not appearing in the string if required) instead, as in:

my $basename   = q!/home/jebsky/safehouse/music/mp3!;
my $dirpath    = qq!${basename}/${initial}/${artist}!;
my $filename   = qq!${year}-${album}/${track}-${artist}-${title}.mp3!;

$outname       = qq!${dirpath}/${filename}!;

This way, you'll rarely have to quote any char in the string.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜