vorrei suggerire una soluzione che si differenzia da quello vecchio. Si noti che quello vecchio utilizza il deprecatoreturning
. A proposito, è comunque lo specifico per Rails, e non hai menzionato esplicitamente Rails nella tua domanda (solo come tag). Inoltre, la soluzione esistente non riesce a codificare .doc.pdf
in _doc.pdf
, come richiesto. E, naturalmente, non collassa i underscore in uno solo.
Ecco la mia soluzione:
def sanitize_filename(filename)
# Split the name when finding a period which is preceded by some
# character, and is followed by some character other than a period,
# if there is no following period that is followed by something
# other than a period (yeah, confusing, I know)
fn = filename.split /(?<=.)\.(?=[^.])(?!.*\.[^.])/m
# We now have one or two parts (depending on whether we could find
# a suitable period). For each of these parts, replace any unwanted
# sequence of characters with an underscore
fn.map! { |s| s.gsub /[^a-z0-9\-]+/i, '_' }
# Finally, join the parts with a period and return the result
return fn.join '.'
end
Non hai specificato tutti i dettagli circa la conversione. Così, sto facendo le seguenti ipotesi:
- Ci dovrebbe essere al massimo un'estensione del file, il che significa che ci dovrebbe essere al massimo un periodo nel nome del file
- Trailing periodi non segnare l'inizio di un estensione
- periodi leading non segnano l'inizio di un'estensione
- Qualsiasi sequenza di caratteri oltre
A
- Z
, a
- z
, 0
- 9
e -
dovrebbero essere ridotte in una singola _
(ad es. sottolineatura stesso considerato come un carattere non consentito, e la stringa '$%__°#'
diventerebbe '_'
- anziché '___'
dalle parti '$%'
, '__'
e '°#'
)
La parte complicata di questo è dove ho diviso il nome del file nella parte principale ed estensione. Con l'aiuto di un'espressione regolare, sto cercando l'ultimo periodo, che è seguito da qualcosa di diverso da un punto, in modo che non ci siano periodi successivi che corrispondono agli stessi criteri nella stringa. Deve, tuttavia, essere preceduto da qualche carattere per assicurarsi che non sia il primo carattere nella stringa.
I miei risultati da testare la funzione:
1.9.3p125 :006 > sanitize_filename 'my§document$is°° very&interesting___thisIs%nice445.doc.pdf'
=> "my_document_is_very_interesting_thisIs_nice445_doc.pdf"
che credo sia quello che avete richiesto. Spero che questo sia abbastanza carino ed elegante.
fonte
2012-05-30 19:41:36
È una bella domanda. Vorrei avere una risposta stdlib –