Сопоставление с образцом и значения заполнителя - PullRequest
7 голосов
/ 31 октября 2008

Я пишу приложение, которое использует правила переименования для переименования списка файлов на основе информации, предоставленной пользователем. Файлы могут иметь непоследовательные имена или имена файлов могут быть непротиворечивыми. Пользователь выбирает список файлов и вводит информацию о файлах (для MP3 - это Исполнитель, Заголовок, Альбом и т. Д.). Используя правило переименования (пример ниже), программа использует введенную пользователем информацию для соответствующего переименования файлов.

Однако, если все или некоторые файлы имеют одинаковые имена, я бы хотел, чтобы программа «угадывала» информацию о файле. Это проблема, с которой я столкнулся. Каков наилучший способ сделать это?

Примеры имен файлов:

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

Правило переименования:

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

Программа должна правильно определить имя исполнителя, номер дорожки, название и название альбома.

Опять же, каков наилучший способ сделать это? Я думал о регулярных выражениях, но я немного запутался.

Ответы [ 5 ]

3 голосов
/ 31 октября 2008

Проще всего было бы заменить каждый %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 голос
/ 31 октября 2008

Не ответ на заданный вами вопрос, но ID3 tag библиотека чтения может быть лучшим способом сделать это, когда вы используете MP3. Быстрый Google придумал: C # ID3 Library .

Что касается угадывания того, какие позиции строк содержат исполнителя, альбом и название песни ... Первое, о чем я могу подумать, это то, что если у вас есть хороший выбор для работы, скажем, с несколькими альбомами, вы можете сначала увидеть, какая позиция повторяется больше всего, который будет исполнителем, который повторяет второй наиболее (альбом) и который повторяет меньше всего (название песни).

В противном случае кажется трудным сделать предположение, основываясь только на нескольких строках в имени файла ... не могли бы вы попросить пользователя также ввести соответствующее выражение для имени файла, которое описывает порядок полей?

0 голосов
/ 02 ноября 2008

Я написал файл переименования командной строки --- 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
0 голосов
/ 31 октября 2008

Чтобы уточнить, у меня DO есть шаблон для сопоставления имен файлов с *. 1003 *

Я не знаю имени файла или шаблона заранее, все время выполнения.

Шаблон:

%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

Опять же, формат и имена файлов не всегда одинаковы.

0 голосов
/ 31 октября 2008

Имена файлов в вашем примере кажутся мне довольно последовательными. Вы можете просто сделать string.Split () и добавить каждый элемент результирующего массива к соответствующей информации тега.

Угадай, в какой позиции какая информация тега будет включать тонны эвристики.

Btw. Папки, которые содержат файлы песен, обычно также имеют какой-то шаблон в названии, например,

1998 - Семь

1999 - Перископ

2000 - CO2

Здесь используется формат% Year% -% AlbumName%, который может помочь вам определить, какой элемент в имени файла является альбомом.

...