模式匹配和占位符值
本文关键字:占位符 模式匹配 | 更新日期: 2023-09-27 17:47:47
我正在编写一个应用程序,该应用程序使用重命名规则根据用户提供的信息重命名文件列表。 文件的名称可能一开始就不一致,或者文件名可能一致。 用户选择文件列表,并输入有关文件的信息(对于MP3,它们将是艺术家,标题,专辑等(。 使用重命名规则(下面的示例(,程序使用用户输入的信息相应地重命名文件。
但是,如果所有或部分文件的名称一致,我想允许程序"猜测"文件信息。 这就是我遇到的问题。 最好的方法是什么?
示例文件名:
Kraftwerk-Kraftwerk-01-RuckZuck.mp3
Kraftwerk-Autobahn-01-Autobahn.mp3
Kraftwerk-Computer World-03-Numbers.mp3
重命名规则:
%Artist%-%Album%-%Track%-%Title%.mp3
该程序应正确推断艺术家,曲目编号,标题和专辑名称。
同样,最好的方法是什么? 我在想正则表达式,但我有点困惑。
最简单的方法是将每个%Label%
替换为(?<Label>.*?)
,并转义任何其他字符。
%Artist%-%Album%-%Track%-%Title%.mp3
成为
(?<Artist>.*?)-(?<Album>.*?)-(?<Track>.*?)-(?<Title>.*?)'.mp3
然后,将每个组件放入命名的捕获组中。
Dictinary<string,string> match_filename(string rule, string filename) {
Regex tag_re = new Regex(@'%('w+)%');
string pattern = tag_re.Replace(Regex.escape(rule), @'(?<$1>.*?)');
Regex filename_re = new Regex(pattern);
Match match = filename_re.Match(filename);
Dictionary<string,string> tokens =
new Dictionary<string,string>();
for (int counter = 1; counter < match.Groups.Count; counter++)
{
string group_name = filename_re.GroupNameFromNumber(counter);
tokens.Add(group_name, m.Groups[counter].Value);
}
return tokens;
}
但是,如果用户省略了分隔符,或者如果分隔符可以包含在字段中,您可能会得到一些奇怪的结果。对于%Artist%%Album%
来说,模式将变得(?<Artist>.*?)(?<Album>.*?)
,这相当于.*?.*?
。模式不知道在哪里分裂。
如果您知道某些字段的格式,例如曲目编号,则可以解决此问题。如果将%Track%
转换为(?<Track>'d+)
,则模式将知道文件名中的任何数字都必须是Track
。
不是您提出的问题的答案,但是当您使用 MP3 时,ID3 标签阅读库可能是更好的方法。 谷歌快速想出了:C# ID3库。
至于猜测哪些弦位置包含艺术家、专辑和歌曲名称......我能想到的第一件事是,如果你有一个好的选择,比如几张专辑,你可以首先看到哪个位置重复最多,哪个是艺术家,哪个重复次数第二多(专辑(,哪个重复最少(歌曲标题(。
否则,仅根据文件名中的几个字符串进行猜测似乎很困难......您能否要求用户也为描述字段顺序的文件名输入匹配表达式?
你例子中的文件名对我来说似乎非常一致。你可以简单地做字符串。Split(( 并将结果数组的每个元素添加到其相应的标记信息中。
猜测哪个位置是哪个标签信息将涉及大量的启发式方法。
顺便说一句,包含歌曲文件的文件夹通常在其名称中也有一些模式,例如
1998 - 七
1999 - 潜望镜
2000 - 二氧化碳
此处的格式为 %Year% - %AlbumName%,这可能有助于您识别文件名中的哪个元素是相册。
澄清一下,我确实有一个模式来匹配文件名。
我事先不知道文件名或模式,这都是运行时。
模式:
%艺术家%-%专辑%-%曲目%-%标题%.mp3
文件名:
Kraftwerk-Kraftwerk-01-RuckZuck.mp3Kraftwerk-Autobahn-01-Autobahn.mp3Kraftwerk-Computer World-03-Numbers.mp3
预期成果:
艺术家专辑曲目名称Kraftwerk Kraftwerk 01 RuckZuckKraftwerk Autobahn 01 Autobahn卡夫电脑世界 01 数字
同样,格式和文件名并不总是相同的。
我已经编写了一个命令行文件重命名器---RenameWand ---,它执行您所描述的模式匹配。虽然它是用Java编写的,但我认为您可能会对一些源代码和使用文档感兴趣。程序可以做什么的简单示例:
源模式(用户指定(:
<artist>-<album>-<track>-<title>.mp3
目标模式(用户指定(:
<title.upper>-<3|track+10>-<album.lower>-<artist>.mp3
原始文件名:
Kraftwerk-Computer World-03-Numbers.mp3
重命名的文件名:
NUMBERS-013-computer world-Kraftwerk.mp3