Pattern matching and placeholder values

Easiest would be to replace each %Label% with (?<Label>.*?), and escape any other characters.

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

becomes

(?<Artist>.*?)-(?<Album>.*?)-(?<Track>.*?)-(?<Title>.*?)\.mp3

You would then get each component into named capture groups.

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;
}

But if the user leaves out the delimiters, or if the delimiters could be contained within the fields, you could get some strange results. The pattern would for %Artist%%Album% would become (?<Artist>.*?)(?<Album>.*?) which is equivalent to .*?.*?. The pattern wouldn't know where to split.

This could be solved if you know the format of certain fields, such as the track-number. If you translate %Track% to (?<Track>\d+) instead, the pattern would know that any digits in the filename must be the Track.

Tags:

C#

Regex