模式匹配和占位符值

时间:2008-10-30 21:00:11

标签: c# .net regex pattern-matching

我正在编写一个使用重命名规则的应用程序,根据用户提供的信息重命名文件列表。文件可能以不一致的名称开头,或者文件名可能是一致的。用户选择文件列表,并输入有关文件的信息(对于MP3,它们将是艺术家,标题,专辑等)。使用重命名规则(例如下面的代码),程序使用用户输入的信息相应地重命名文件。

但是,如果所有或部分文件都是一致的,我想让程序“猜测”文件信息。这就是我遇到的问题。这样做的最佳方式是什么?

示例文件名:

Kraftwerk-Kraftwerk-01-RuckZuck.mp3
Kraftwerk-Autobahn-01-Autobahn.mp3
Kraftwerk-Computer World-03-Numbers.mp3

重命名规则:

%Artist%-%Album%-%Track%-%Title%.mp3

该节目应正确推断艺术家,曲目编号,标题和专辑名称。

同样,最好的方法是什么?我在思考正则表达式,但我有点困惑。

5 个答案:

答案 0 :(得分:3)

最简单的方法是用%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

答案 1 :(得分:1)

不是您提出的问题的答案,但是当您使用MP3时,ID3 tag阅读库可能是更好的方法。一个快速的谷歌想出了:C# ID3 Library

至于猜测哪些字符串位置包含艺术家,专辑和歌曲标题......我能想到的第一件事是,如果你有一个很好的选择,比如几张专辑,你可以先看看哪个位置重复最多的,这将是艺术家,重复第二多(专辑),并重复最少(歌曲标题)。

否则,仅根据文件名中的几个字符串进行制作似乎是一个困难的猜测...您是否可以要求用户输入描述字段顺序的文件名的匹配表达式?< / p>

答案 2 :(得分:0)

您示例中的文件名对我来说似乎非常一致。 您可以简单地执行string.Split()并将结果数组的每个元素添加到其相应的标记信息中。

猜测哪个标记信息涉及启发式的TONS。

顺便说一下。包含歌曲文件的文件夹通常也会在其名称中包含一些模式,例如

1998 - Seven

1999 - Periscope

2000 - 二氧化碳

此处的格式为%Year% - %AlbumName%,可帮助您确定文件名中的哪个元素是相册。

答案 3 :(得分:0)

为了澄清,我 DO 有一个匹配文件名的模式。

我提前知道文件名或模式,它都是运行时。

模式:

%Artist%-%Album%-%Track%-%Title%.mp3

文件名:

Kraftwerk-Kraftwerk-01-RuckZuck.mp3
Kraftwerk-Autobahn-01-Autobahn.mp3
Kraftwerk-Computer World-03-Numbers.mp3

预期结果:

Artist    Album          Track Title
Kraftwerk Kraftwerk      01    RuckZuck
Kraftwerk Autobahn       01    Autobahn
Kraftwerk Computer World 01    Numbers

同样,格式和文件名并不总是相同。

答案 4 :(得分:0)

我编写了一个命令行文件重命名器--- 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