Domanda

Sto scrivendo un'applicazione che utilizza le regole di ridenominazione per rinominare un elenco di file in base alle informazioni fornite dall'utente.I file potrebbero avere nomi incoerenti all'inizio oppure i nomi dei file potrebbero essere coerenti.L'utente seleziona un elenco di file e inserisce le informazioni sui file (per gli MP3, sarebbero Artista, Titolo, Album, ecc.).Utilizzando una regola di ridenominazione (esempio seguente), il programma utilizza le informazioni immesse dall'utente per rinominare i file di conseguenza.

Tuttavia, se tutti o alcuni file hanno nomi coerenti, vorrei consentire al programma di "indovinare" le informazioni sul file.Questo è il problema che sto riscontrando.Qual è il modo migliore per farlo?

Nomi file di esempio:

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

Rinomina regola:

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

Il programma dovrebbe dedurre correttamente l'artista, il numero della traccia, il titolo e il nome dell'album.

Ancora una volta, qual è il modo migliore per farlo?Stavo pensando alle espressioni regolari, ma sono un po' confuso.

È stato utile?

Soluzione

La cosa più semplice sarebbe sostituirli tutti %Label% con (?<Label>.*?), e sfuggi a qualsiasi altro personaggio.

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

diventa

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

Dovresti quindi inserire ciascun componente in gruppi di acquisizione denominati.

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

Ma se l'utente tralascia i delimitatori o se i delimitatori potrebbero essere contenuti all'interno dei campi, potresti ottenere risultati strani.Il modello sarebbe per %Artist%%Album% potrebbe diventare (?<Artist>.*?)(?<Album>.*?) che è equivalente a .*?.*?.Lo schema non saprebbe dove dividersi.

Questo potrebbe essere risolto se conosci il formato di alcuni campi, come il numero della traccia.Se traduci %Track% A (?<Track>\d+) invece, il modello saprebbe che qualsiasi cifra nel nome del file deve essere il Track.

Altri suggerimenti

Non la risposta alla domanda che hai posto, ma una tag ID3 potrebbe essere un modo migliore per farlo quando si utilizzano MP3. Un rapido Google ha prodotto: Libreria C # ID3 .

Per quanto riguarda indovinare quali posizioni delle stringhe contengono l'artista, l'album e il titolo della canzone ... la prima cosa che mi viene in mente è che se hai una buona selezione con cui lavorare, diciamo diversi album, potresti prima vedere quale posizione ripete di più, che sarebbe l'artista, che ripete il secondo più (album) e che ripete il meno (titolo del brano).

Altrimenti, sembra difficile indovinare basandosi solo su alcune stringhe nel nome del file ... potresti chiedere all'utente di inserire anche un'espressione corrispondente per il nome del file che descrive l'ordine dei campi?

I nomi dei file nel tuo esempio mi sembrano abbastanza coerenti. Puoi semplicemente fare string.Split () e aggiungere ogni elemento dell'array risultante alle sue informazioni tag corrispondenti.

Indovinare in quale posizione si trovano le informazioni sui tag che implicherebbero tonnellate di euristica.

Btw. le cartelle che contengono file di brani di solito hanno anche un modello nel loro nome, ad esempio

1998 - Seven

1999 - Periscope

2000 - CO2

Il formato qui è% Year% -% AlbumName%, che potrebbe aiutarti a identificare quale elemento nel nome del file è l'album.

Per chiarire, DO ho uno schema per abbinare i nomi dei file.

Non conosco il nome file o il modello in anticipo, è tutto runtime.

Modello:

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

I nomi dei file:

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

Risultato atteso:

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

Ancora una volta, il formato e i nomi dei file non sono sempre gli stessi.

Ho scritto un renamer di file della riga di comando --- RenameWand --- che fa il tipo di pattern matching che stai descrivendo. È in Java però, ma penso che parte del codice sorgente e della documentazione sull'utilizzo possano essere di tuo interesse. Un semplice esempio di cosa può fare il programma:

Pattern sorgente (specificato dall'utente):

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

Target Pattern (specificato dall'utente):

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

Nome file originale:

Kraftwerk-Computer World-03-Numbers.mp3

Nome file rinominato:

NUMBERS-013-computer world-Kraftwerk.mp3
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top