Удалить расширение файла и путь из строки в Perl

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

Например:

/path/to/file/fileName.txt     # results in "fileName"
fileName.txt                   # results in "fileName"
/path/to/file/file.with.periods.txt    # results in "file.with.periods" 

Итак, в основном, я хочу удалить все до и включая последний «/», если он присутствует, а также последний «.». вместе с любыми метасимволами после него.

Извините за такой вопрос новичка, но я новичок в perl.


person Chris    schedule 08.09.2010    source источник


Ответы (3)


Для переносимого получения базового имени файла с полным путем я бы рекомендовал File::Basename модуль, входящий в состав ядра.

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

(my $without_extension = $basename) =~ s/\.[^.]+$//;
person rafl    schedule 08.09.2010
comment
Что касается basename, я только что прочитал: эта функция предназначена для совместимости с командой basename(1) оболочки Unix. Он НЕ всегда возвращает часть имени файла пути, как можно было бы ожидать. Чтобы быть в безопасности, если вы хотите, чтобы часть имени файла пути использовала fileparse(). - person Chris; 08.09.2010
comment
Да, в модуле File::Basename больше одной функции, и все они делают разные вещи. Выберите тот, который делает то, что вы хотите. Кроме того, аналогичная функциональность существует в File::Spec как splitpath - person rafl; 08.09.2010

Хотя другие ответили, немного прочитав базовое имя на ответ rafl:

($file,$dir,$ext) = fileparse($fullname, qr/\.[^.]*/);
# dir="/usr/local/src/" file="perl-5.6.1.tar" ext=".gz"

Кажется, решить проблему в одной строке.

Есть ли какие-либо проблемы, связанные с этим, в отличие от других решений?

person Chris    schedule 08.09.2010

Предполагая, что разделителем путей является '/', вы можете сделать это с помощью пары замен:

$name =~ s{^.*/}{};     # remove the leading path  
$name =~ s{\.[^.]+$}{}; # remove the extension

Вы также можете написать это как одну замену:

$name =~ s{^.*/|\.[^.]+$}{}g;
person Eugene Yarmash    schedule 08.09.2010
comment
Просто и эффективно. Спасибо. - person Andy; 19.10.2011
comment
@Phalgun [^.] — это класс символов с отрицательным знаком, т. е. он будет соответствовать любому символу, который не является точкой (.). (Обратите внимание, что . теряет свое особое значение при использовании внутри класса символов.) [^.]+ будет соответствовать одному или нескольким таким символам. Подробнее см. perlre. - person Eugene Yarmash; 22.08.2019