Сопоставление с шаблоном и значения-заполнители

StackOverflow https://stackoverflow.com/questions/251759

Вопрос

Я пишу приложение, которое использует правила переименования для переименования списка файлов на основе информации, предоставленной пользователем.Файлы могут иметь несогласованные имена с самого начала, или имена файлов могут быть согласованными.Пользователь выбирает список файлов и вводит информацию о файлах (для 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.

Другие советы

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

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

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

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

Угадывание того, в какой позиции находится информация о теге, потребовало бы ТОННЫ эвристики.

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

1998 - Семь

1999 - Перископ

2000 - CO2

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

Чтобы внести ясность, я ДЕЛАЙ создайте шаблон для сопоставления имен файлов.

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

Узор:

%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

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

Я написал переименователь файла командной строки --- 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top