Regex Perl正则表达式只输出可以用作unix文件名的字符
我为自己写了一个基本的mp3组织脚本。我有一行:Regex Perl正则表达式只输出可以用作unix文件名的字符,regex,perl,mp3,Regex,Perl,Mp3,我为自己写了一个基本的mp3组织脚本。我有一行:$outname=“/home/jebsky/safehouse/music/mp3/”$最初的。"/" . $艺术家。"/" . $年。”——”$专辑"/" . $轨道。“-”$艺术家$标题“.mp3” 我需要一个正则表达式来更改$outname,这样任何不安全的文件名字符都会被下划线替换如果您的任何组件包含“/”,那么在将它们组装成$outname之前,您真的需要对它们进行替换 哪些字符是安全的可能因操作系统和/或文件系统而异。 许多文件系统对
$outname=“/home/jebsky/safehouse/music/mp3/”$最初的。"/" . $艺术家。"/" . $年。”——”$专辑"/" . $轨道。“-”$艺术家$标题“.mp3”代码>
我需要一个正则表达式来更改$outname
,这样任何不安全的文件名字符都会被下划线替换如果您的任何组件包含“/”,那么在将它们组装成$outname之前,您真的需要对它们进行替换
哪些字符是安全的可能因操作系统和/或文件系统而异。
许多文件系统对“/”和nul以外的任何字符都没有问题。由于文件系统不允许的其他原因,您最好决定要保留哪些字符
以下仅保留字母和数字,将其他字符的序列替换为ux:
for ( $initial, $artist, $year, $album, $track, $title ) {
s/[^A-Za-z0-9]+/_/g;
}
如果您的任何组件包含“/”,那么在将它们组装成$outname之前,您确实希望对它们进行替换
哪些字符是安全的可能因操作系统和/或文件系统而异。
许多文件系统对“/”和nul以外的任何字符都没有问题。由于文件系统不允许的其他原因,您最好决定要保留哪些字符
以下仅保留字母和数字,将其他字符的序列替换为ux:
for ( $initial, $artist, $year, $album, $track, $title ) {
s/[^A-Za-z0-9]+/_/g;
}
转义字符串中所有非字母字符的一种快速方法是使用\Q和\U运算符,如中所示:
# assuming $outname already contains the required path and
# globally "unescaping" file chars / and .
($outname = "\Q$outname\U") =~ s/\\([\/\.])/$1/g;
有一点需要考虑的是,像你这样的长线猫往往都很难阅读和维护。表示此操作的更好方法可能是将其分解为逻辑单元,如:
my $basename = '/home/jebsky/safehouse/music/mp3';
my $dirpath = "${basename}/${initial}/${artist}/${year}-${album}/";
my $filename = "${track}-${artist}-${title}.mp3";
$outname = "${dirpath}/${filename}";
在字符串中,将变量表示为“${varname}”可以确保varname后面的字符不会干扰它,即使var后面的下一个字符不是字母数字,这通常是一个好主意,因为它清楚地标记了字符串中的变量
最后,我认为最好不要使用''''和'\''作为字符串分隔符,因为如果字符串包含分隔符,它们需要引号
使用qq//和q//分隔符(如果需要,将/替换为字符串中不显示的字符),如中所示:
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}!;
这样,您几乎不必在字符串中引用任何字符。一种快速转义字符串中所有非字母字符的方法是使用\Q和\U运算符,如中所示:
# assuming $outname already contains the required path and
# globally "unescaping" file chars / and .
($outname = "\Q$outname\U") =~ s/\\([\/\.])/$1/g;
有一点需要考虑的是,像你这样的长线猫往往都很难阅读和维护。一种更好的表示这种操作的方法可能是把它分解成逻辑单元,比如:
my $basename = '/home/jebsky/safehouse/music/mp3';
my $dirpath = "${basename}/${initial}/${artist}/${year}-${album}/";
my $filename = "${track}-${artist}-${title}.mp3";
$outname = "${dirpath}/${filename}";
在字符串中,将变量表示为“${varname}”可以确保varname后面的字符不会干扰它,即使var后面的下一个字符不是字母数字,这通常是一个好主意,因为它清楚地标记了字符串中的变量
最后,我认为最好不要使用''''和'\''作为字符串分隔符,因为如果字符串包含分隔符,它们需要引号
使用qq//和q//分隔符(如果需要,将/替换为字符串中不显示的字符),如中所示:
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}!;
这样,您几乎不必在字符串中引用任何字符。非ASCII(非英语)字母如何?我认为这对那些人不起作用。您需要将shell错误字符(每个shell/OS)列入黑名单,或者更改正则表达式以将“字母”范围扩展到A_Za-z之外,尤其是可以作为MP3的一部分的非字母数字字符(撇号、破折号、空格)@DVK:我从我的音乐文件中去掉了所有的内容:)我在推荐原创海报,让他自己制作一套。非ASCII(非英语)字母呢?我认为这对那些人不起作用。你要么需要将shell中的坏字符(每个shell/OS)列入黑名单,要么改变你的正则表达式,将“字母”范围扩大到一个更大的范围——特别是mp3(撇号、破折号、空格)@DVK:I从我的音乐文件中去掉所有这些:)我建议原创海报制作一套自己的。