Pergunta

Eu estou escrevendo um aplicativo que usa renomear regras para renomear uma lista de arquivos com base em informações fornecidas pelo usuário. Os arquivos podem ser inconsistente chamado para começar, ou os nomes de arquivos podem ser consistente. O usuário seleciona uma lista de arquivos e informações entradas sobre os arquivos (para MP3s, eles seriam artista, título, álbum, etc). Usando uma regra de mudança de nome (exemplo abaixo), o programa utiliza a informação digitada pelo usuário para renomear os arquivos em conformidade.

No entanto, se todos ou alguns dos arquivos são nomeados de forma consistente, eu gostaria de permitir que o programa de 'adivinhar' as informações do arquivo. Esse é o problema que estou tendo. Qual é a melhor maneira de fazer isso?

nomes de arquivos de exemplo:

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

Regra Rename:

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

O programa deve deduzir corretamente o artista, número de faixa, título eo nome do álbum.

Mais uma vez, qual é a melhor maneira de fazer isso? Eu estava pensando expressões regulares, mas estou um pouco confuso.

Foi útil?

Solução

Mais fácil seria a de substituir cada %Label% com (?<Label>.*?), e escapar quaisquer outros caracteres.

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

se torna

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

Você, então, obter cada componente em grupos de captura nomeados.

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

Mas se as folhas de usuários fora dos delimitadores, ou se os delimitadores poderiam ser contido dentro dos campos, você pode obter alguns resultados estranhos. O padrão seria para %Artist%%Album% se tornaria (?<Artist>.*?)(?<Album>.*?) o que equivale a .*?.*?. O padrão não saberia por onde para dividir.

Esta poderia ser resolvido se você sabe o formato de determinados campos, como a faixa-número. Se você traduzir %Track% para (?<Track>\d+) vez, o padrão saberia que quaisquer dígitos no nome do arquivo deve ser o Track.

Outras dicas

Nem a resposta para a pergunta que você fez, mas um ID3 tag biblioteca de leitura pode ser uma maneira melhor de fazer isso quando você estiver usando MP3s. Uma rápida Google surgiu com:. C # ID3 Biblioteca

Como para adivinhar que as posições de corda segurar o artista, álbum e canção título ... a primeira coisa que eu posso pensar é que se você tem uma boa selecção de trabalhar, dizem vários álbuns, você pode primeiro ver qual posição repete a mais, o que seria o artista, que repete o segundo mais (álbum) e que repete o (título da canção) menos.

Caso contrário, parece que um palpite difícil de fazer com base apenas em algumas cordas no nome do arquivo ... você poderia perguntar ao usuário expressão uma correspondência também entrada para o nome do arquivo que descreve a ordem dos campos

Os nomes de arquivos no seu exemplo parece bastante consistente para mim. Você pode simplesmente fazer string.split () e adicionar cada elemento da matriz resultante para seu segundo informações da etiqueta.

Adivinhar em que posição é que a informação tag envolveria TONELADAS de heurísticas.

Btw. pastas que contenham arquivos de música geralmente têm algum padrão em seu nome, bem como, F.E..

1998 - Sete

1999 - Periscópio

2000 - CO2

O formato aqui é% Ano% -.% ALBUMNAME%, que podem ajudar você a identificar qual elemento no nome do arquivo é o álbum

Para esclarecer, eu DO têm um padrão para coincidir com os nomes de arquivos contra.

Eu não sei o nome do arquivo ou padrão antes do tempo, isso é tudo o tempo de execução.

Padrão:

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

Nomes de arquivos:

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

Resultado esperado:

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

Mais uma vez, o formato e nomes de arquivos não são sempre os mesmos.

Eu escrevi um arquivo de linha de comando renamer --- RenameWand --- que faz o tipo de correspondência de padrões que você está descrevendo. É em Java, porém, mas eu acho que parte do código-fonte e documentação de uso podem ser de seu interesse. Um exemplo simples do que o programa pode fazer:

Padrão Fonte (user-especificada):

<artist>-<album>-<track>-<title>.mp3

Pattern Target (user-especificada):

<title.upper>-<3|track+10>-<album.lower>-<artist>.mp3

Nome do arquivo original:

Kraftwerk-Computer World-03-Numbers.mp3

Renomeado Matrícula:

NUMBERS-013-computer world-Kraftwerk.mp3
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top