Регулярное выражение для удаления расширения файла

Мне нужно регулярное выражение, которое может удалить расширение имени файла, возвращая только имя файла.

Вот несколько примеров входов и выходов:

myfile.png     -> myfile
myfile.png.jpg -> myfile.png

Я, очевидно, могу сделать это вручную (т.е. удалить все из последней точки), но я уверен, что существует регулярное выражение, которое может сделать это само по себе.

Только для записи, я делаю это в JavaScript

Ответ 1

/(.*)\.[^.]+$/

Результат будет в первой группе захвата. Однако, вероятно, более эффективно просто найти положение самого правого периода, а затем взять все перед ним, не используя регулярное выражение.

Ответ 2

Просто для полноты: как это можно достичь без регулярных выражений?

var input = 'myfile.png';
var output = input.substr(0, input.lastIndexOf('.')) || input;

|| input заботится о случае, где lastIndexOf() предоставляет -1. Понимаете, это все еще однострочный.

Ответ 3

/^(.+)(\.[^ .]+)?$/

Тестовые случаи, когда это работает, и другие не работают:

  • ". htaccess" (ведущий период)
  • "файл" (без расширения файла)
  • "отправьте на mrs." (без расширения, но заканчивается на abbr.)
  • "версия 1.2 проекта" (без расширения, но все еще содержит период)

Общий поток выше - это, конечно, "искаженные" расширения файлов. Но вы всегда должны думать об этих угловых случаях.: P

Тестовые случаи, когда это не удается:

  • "версия 1.2" (расширение файла отсутствует, но "появляется" ).
  • "name.tar.gz" (если вы рассматриваете это как "составное расширение" и хотели, чтобы он разделился на "имя" и ".tar.gz" )

Как справиться с этими проблемами является проблематичным и наилучшим образом определяется на основе проекта.

Ответ 4

Регулярное выражение для соответствия шаблону:

/\.[^.]*$/

Он находит символ точки (\.), За которым следуют 0 или более символов, которые не являются точками ([^.] *), За которыми следует конец строки ($).

console.log( 
  "aaa.bbb.ccc".replace(/\.[^.]*$/,'')
)

Ответ 5

/^(.+)(\.[^ .]+)?$/

Выше неправильный шаблон - он всегда будет включать расширение. Это из-за того, как работает javascript regex engine. Ток (\.[^ .]+) не является обязательным, поэтому движок будет успешно соответствовать всей строке с помощью (.+) 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, но включая и полные пути

Ответ 6

еще один способ сделать это без регулярных выражений ("опосайт" версии @Rahul, не использующий pop() для удаления)

Не требуется ссылаться на переменную дважды, поэтому ее проще встроить

filename.split('.').slice(0,-1).join()

Ответ 7

Это также сделает это:)

'myfile.png.jpg'.split('.').reverse().slice(1).reverse().join('.');

Я бы придерживался regexp, хотя... = P

Ответ 8

  return filename.split('.').pop();

это воплотит ваше желание. Но не регулярный способ выражения.

Ответ 9

В javascript вы можете вызвать метод Replace(), который будет заменен на основе регулярного выражения.

Это регулярное выражение будет соответствовать всем значениям от начала строки до конца и удалять что-либо после последнего периода, включая период.

/^(.*)\..*$/

Как реализовать замену можно найти в этом вопросе Stackoverflow.

Вопрос о регулярном выражении Javascript