Я хотел бы предложить решение, которое отличается от старого. Обратите внимание, что старый использует устаревший returning
. Кстати, это в любом случае характерно для Rails , и вы не упомянули Rails в своем вопросе (только как тег). Кроме того, существующее решение не может закодировать .doc.pdf
в _doc.pdf
, как вы и просили. И, конечно же, он не сводит подчеркивания в одно целое.
Вот мое решение:
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
Вы не указали все подробности о конверсии. Таким образом, я делаю следующие предположения:
- Должно быть не более одного расширения имени файла, что означает, что в имени файла должно быть не более одного периода
- Конечные периоды не отмечают начало расширения
- Ведущие периоды не отмечают начало продления
- Любая последовательность символов за пределами
A
- Z
, a
- z
, 0
- 9
и -
должна быть свернута в один _
(т.е. подчеркивание само по себе считается как запрещенный символ, и строка '$%__°#'
станет '_'
- вместо '___'
из частей '$%'
, '__'
и '°#'
)
Сложная часть этого - разделение имени файла на основную часть и расширение. С помощью регулярного выражения я ищу последний период, за которым следует нечто иное, чем период, чтобы в строке не было следующих периодов, соответствующих одинаковым критериям. Однако ему должен предшествовать какой-то символ, чтобы быть уверенным, что это не первый символ в строке.
Мои результаты тестирования функции:
1.9.3p125 :006 > sanitize_filename 'my§document$is°° very&interesting___thisIs%nice445.doc.pdf'
=> "my_document_is_very_interesting_thisIs_nice445_doc.pdf"
что я думаю, это то, что вы просили. Я надеюсь, что это красиво и элегантно.