Регулярное выражение для удаления расширения файла
-
10-07-2019 - |
Вопрос
Мне нужно регулярное выражение, которое могло бы удалить расширение имени файла, возвращая только имя файла.
Вот несколько примеров входов и выходов:
myfile.png -> myfile
myfile.png.jpg -> myfile.png
Очевидно, я могу сделать это вручную (т. е. удалив все, начиная с последней точки), но я уверен, что существует регулярное выражение, которое может сделать это само по себе.
Для справки: я делаю это на JavaScript.
Решение
/(.*)\.[^.]+$/
Результат будет в этой первой группе захвата. Однако, вероятно, более эффективно просто найти позицию самого правого периода и затем взять все перед ним, не используя регулярное выражение.
Другие советы
Просто для полноты: как этого можно достичь без регулярных выражений?
var input = 'myfile.png';
var output = input.substr(0, input.lastIndexOf('.')) || input;
|| input
заботится о случае, когда lastIndexOf ()
предоставляет -1
. Вы видите, это все еще однострочник.
/^(.+)(\.[^ .]+)?$/
Тестовые случаи, когда это работает, а другие терпят неудачу:
- «.htaccess» (ведущий период)
- «файл» (без расширения файла)
- «Отправить миссис». (Нет расширения, но заканчивается в ABBR.)
- «версия проекта 1.2» (без расширения, но все же содержит точку)
Общая тема выше, конечно же, — «неверные» расширения файлов.Но всегда нужно думать об этих крайних случаях.:П
Тестовые случаи, когда это не удается:
- «версия 1.2» (без расширения файла, но «похоже» оно есть)
- «name.tar.gz» (если вы рассматриваете это как «составное расширение» и хотите разделить его на «name» и «.tar.gz»)
Как с этим справиться, проблематично, и лучше всего решать это в зависимости от конкретного проекта.
Регулярное выражение, соответствующее шаблону:
/\.[^.]*$/
Он находит символ точки (\.), за которым следует 0 или более символов, не являющихся точками ([^.]*), за которым следует конец строки ($).
console.log(
"aaa.bbb.ccc".replace(/\.[^.]*$/,'')
)
/^(.+)(\.[^ .]+)?$/
Вышеуказанный шаблон неверен - он всегда будет также включать расширение. Это из-за того, как работает механизм регулярных выражений javascript. Токен (\. [^.] +)
является необязательным, поэтому механизм успешно сопоставит всю строку с (. +)
http://cl.ly/image/3G1I3h3M2Q0M
Вот мое проверенное решение регулярных выражений.
Шаблон будет соответствовать filenameNoExt с / без расширения в пути, с учетом разделителей как косой черты, так и обратной косой черты
var path = "c:\some.path/subfolder/file.ext"
var m = path.match(/([^:\\/]*?)(?:\.([^ :\\/.]*))?$/)
var fileName = (m === null)? "" : m[0]
var fileExt = (m === null)? "" : m[1]
рассечение вышеуказанного шаблона:
([^:\\/]*?) // match any character, except slashes and colon, 0-or-more times,
// make the token non-greedy so that the regex engine
// will try to match the next token (the file extension)
// capture the file name token to subpattern \1
(?:\. // match the '.' but don't capture it
([^ :\\/.]*) // match file extension
// ensure that the last element of the path is matched by prohibiting slashes
// capture the file extension token to subpattern \2
)?$ // the whole file extension is optional
http://cl.ly/image/3t3N413g3K09
http://www.gethifi.com/tools/regex
Это будет охватывать все случаи, упомянутые @RogerPate, но также включая полные пути
другой способ сделать это без регулярных выражений («опозит» версии @ Rahul, без использования pop () для удаления)
Нет необходимости ссылаться на переменную дважды, поэтому проще встроить
filename.split('.').slice(0,-1).join()
Это тоже будет сделано:)
'myfile.png.jpg'.split('.').reverse().slice(1).reverse().join('.');
Хотя я бы придерживался регулярного выражения ... = P
return filename.split('.').pop();
это сделает ваше желание сбудется. Но не способ регулярного выражения.
В javascript вы можете вызвать метод Replace (), который заменит на основе регулярного выражения.
Это регулярное выражение будет соответствовать всему от начала строки до конца и удалять все после последнего периода, включая период.
/^(.*)\..*$/
Как реализовать замену можно найти в этом вопросе Stackoverflow.