Jak mogę uzyskać rozszerzenia plików za pomocą JavaScript?


501

Zobacz kod:

var file1 = "50.xsl";
var file2 = "30.doc";
getFileExtension(file1); //returns xsl
getFileExtension(file2); //returns doc

function getFileExtension(filename) {
    /*TODO*/
}

Odpowiedzi:


794

Nowsza edycja: Wiele rzeczy zmieniło się od czasu opublikowania tego pytania - w poprawionej odpowiedzi Wallacera jest wiele naprawdę dobrych informacji , a także doskonały podział VisioN


Edycja: Tylko dlatego, że jest to zaakceptowana odpowiedź; odpowiedź wallacera jest rzeczywiście znacznie lepsza:

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

Moja stara odpowiedź:

return /[^.]+$/.exec(filename);

Powinien to zrobić.

Edycja: W odpowiedzi na komentarz PhiLho użyj czegoś takiego:

return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined;

1
Czy dwukrotne wykonanie wyrażenia regularnego nie jest drogie?
Andrew Hedges

5
Poniższa wysoko oceniana odpowiedź jest znacznie lepsza.
fletom

2
Niestety oba rozwiązania zawodzą w przypadku nazw takich jak file i .htaccess .
VisioN

3
Wszystkie możliwe przypadki są przetwarzane w następujący sposób: return filename.split ("."). Slice (1) .pop () || „”;
JustAndrei

1
@JustAndrei Nadal nie wszystkie :) Dla czystej nazwy pliku (basename?), A nie ścieżki, ze względów praktycznych, myślę, że powinien to być. return filename.substring(0,1) === '.' ? '' : filename.split('.').slice(1).pop() || '';Zajmuje się .filetakże plikami (ukrytymi pod Uniksem, jak sądzę). To znaczy, jeśli chcesz zachować to jako linijkę, co jest nieco niechlujne według mojego gustu.
kooker

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

Nie komplikuj :)

Edytować:

To kolejne rozwiązanie, które moim zdaniem jest bardziej wydajne:

return filename.substring(filename.lastIndexOf('.')+1, filename.length) || filename;

Niektóre przypadki narożne są lepiej obsługiwane przez odpowiedź VisioN poniżej, w szczególności pliki bez rozszerzenia ( .htaccessitp. Zawarte).

Jest bardzo wydajny i radzi sobie ze skrzynkami narożnymi w znacznie lepszy sposób, zwracając ""zamiast pełnego łańcucha, gdy przed kropką nie ma kropki ani łańcucha. To bardzo dobrze wykonane rozwiązanie, choć trudne do odczytania. Wstaw go do swojej biblioteki pomocników i po prostu użyj.

Stara edycja:

Bezpieczniejsza implementacja, jeśli zamierzasz uruchomić pliki bez rozszerzenia lub ukryte pliki bez rozszerzenia (patrz komentarz VisioN do odpowiedzi Toma powyżej) byłoby czymś podobnym

var a = filename.split(".");
if( a.length === 1 || ( a[0] === "" && a.length === 2 ) ) {
    return "";
}
return a.pop();    // feel free to tack .toLowerCase() here if you want

Jeśli a.lengthjest jeden, jest to widoczny plik bez rozszerzenia, tj. plik

Jeśli a[0] === ""i a.length === 2jest to ukryty plik bez rozszerzenia tj. .htaccess

Mam nadzieję, że pomoże to rozwiązać problemy z nieco bardziej złożonymi sprawami. Jeśli chodzi o wydajność, uważam, że to rozwiązanie jest nieco wolniejsze niż regex w większości przeglądarek. Jednak do najpopularniejszych celów ten kod powinien być doskonale użyteczny.


4
Nie mogę komentować występu, ale ten z pewnością wygląda czysto! Używam tego. +1
pc1oad1etter

6
ale w tym przypadku nazwa pliku wygląda jak nazwa_pliku.tes.test.jpg. Prosimy wziąć pod uwagę wynik. Mam nadzieję, że to będzie fałsz.
Fero,

19
w takim przypadku wynikiem jest „jpg”
wallacer

1
Znakomity! Dziękuję bardzo. Miło jest widzieć rozwiązanie, które nie używa wyrażenia regularnego; Zrobiłem to z PHP i używa tylko kilku funkcji. +1
Bojangles,

3
@wallacer: Co się stanie, jeśli filenamefaktycznie nie ma rozszerzenia? Czy nie zwróciłoby to po prostu podstawowej nazwy pliku, co byłoby trochę złe?
Nicol Bolas,

287

Następujące rozwiązanie jest szybkie i wystarczająco krótkie , aby można było z niego korzystać w operacjach masowych i oszczędzać dodatkowe bajty:

 return fname.slice((fname.lastIndexOf(".") - 1 >>> 0) + 2);

Oto inne uniwersalne rozwiązanie nieregexp w jednym wierszu:

 return fname.slice((Math.max(0, fname.lastIndexOf(".")) || Infinity) + 1);

Oba działają poprawnie z nazwami bez rozszerzenia (np. Mój_plik ) lub zaczynającymi się od .kropki (np .htaccess ):

 ""                            -->   ""
 "name"                        -->   ""
 "name.txt"                    -->   "txt"
 ".htpasswd"                   -->   ""
 "name.with.many.dots.myext"   -->   "myext"

Jeśli zależy Ci na prędkości, możesz uruchomić test porównawczy i sprawdzić, czy dostarczone rozwiązania są najszybsze, a krótkie niezwykle szybko:

Porównanie prędkości

Jak działa ten krótki:

  1. String.lastIndexOfMetoda zwraca ostatnią pozycję podłańcucha (tj. ".") w danym ciągu (tj fname.). Jeśli podciąg nie zostanie znaleziony, metoda zwraca -1.
  2. „Niedopuszczalne” pozycje kropki w nazwie pliku to -1i 0, które odpowiednio odnoszą się do nazw bez rozszerzenia (np. "name") I nazw zaczynających się od kropki (np ".htaccess".).
  3. Operator przesunięcia w prawo z zerowym wypełnieniem ( >>>), jeśli jest używany z zerem, wpływa na liczby ujemne przekształcane -1do 4294967295i -2do 4294967294, co jest przydatne do pozostania niezmienionej nazwy pliku w przypadkach krawędzi (tutaj jest to podstęp).
  4. String.prototype.slicewyodrębnia część nazwy pliku z pozycji obliczonej zgodnie z opisem. Jeśli liczba pozycji jest większa niż długość ciągu znaków, metoda zwraca "".

Jeśli chcesz bardziej przejrzystego rozwiązania, które będzie działało w ten sam sposób (plus z dodatkową obsługą pełnej ścieżki), sprawdź następującą rozszerzoną wersję. To rozwiązanie będzie wolniejsze niż poprzednie jednowarstwowe, ale o wiele łatwiejsze do zrozumienia.

function getExtension(path) {
    var basename = path.split(/[\\/]/).pop(),  // extract file name from full path ...
                                               // (supports `\\` and `/` separators)
        pos = basename.lastIndexOf(".");       // get last position of `.`

    if (basename === "" || pos < 1)            // if file name is empty or ...
        return "";                             //  `.` not found (-1) or comes first (0)

    return basename.slice(pos + 1);            // extract extension ignoring `.`
}

console.log( getExtension("/path/to/file.ext") );
// >> "ext"

Wszystkie trzy warianty powinny działać w dowolnej przeglądarce internetowej po stronie klienta i mogą być również używane w kodzie NodeJS po stronie serwera.


5
Nie działa. „/home/user/.app/config” zwraca „app / config”, co jest całkowicie błędne.
mrbrdo

33
@mrbrdo Ta metoda nie powinna działać z pełną ścieżką tylko z nazwami plików, zgodnie z żądaniem pytania. Przeczytaj uważnie pytanie przed oddaniem głosu.
VisioN

8
Po co starać się zoptymalizować tak trywialną linię kodu? Operatory tyldy i bitshift są tak rzadko spotykane w JavaScript, że nie mogę poprzeć takiej odpowiedzi. Jeśli potrzeba 5 punktów, aby wyjaśnić, jak działa 1 linia kodu, lepiej przepisać kod, aby był zrozumiały.
Jackson,

6
Szybkość tej jednej linii nie spowoduje zauważalnej różnicy w żadnej aplikacji. Bitowy jest tak rzadko używany, że popularne lintery, takie jak JSLint i JSHint, ostrzegają przed ich użyciem. Obsesja na punkcie wydajności i zwartości tej logiki pogorszyła jakość kodu; jeśli kod wymaga „dodatkowego dochodzenia”, uważam to za „złe”.
Jackson,

10
@Jackson Biorąc pod uwagę, że jest to strona oferująca wiele rozwiązań problemu, posiadanie rozwiązania optymalizującego wydajność nigdy nie jest złą rzeczą. Twoje stwierdzenie „nie zrobi żadnej zauważalnej różnicy w żadnej aplikacji” jest całkowicie oparte na wąskim zakresie możliwych aplikacji, w których można by je wykorzystać. Poza tym może zapewnić komuś, kto patrzy na problem, doświadczenie uczenia się, w którym może zoptymalizować niektóre inny kod, który muszą stworzyć dla aplikacji intensywnie korzystającej z komputerów, którą piszą.
nrylee

33
function getFileExtension(filename)
{
  var ext = /^.+\.([^.]+)$/.exec(filename);
  return ext == null ? "" : ext[1];
}

Testowane z

"a.b"     (=> "b") 
"a"       (=> "") 
".hidden" (=> "") 
""        (=> "") 
null      (=> "")  

Również

"a.b.c.d" (=> "d")
".a.b"    (=> "b")
"a..b"    (=> "b")

Aby działało w IE: var pattern = "^. + \\. ([^.] +) $"; var ext = nowy RegExp (wzorzec);
spc16670,

20
function getExt(filename)
{
    var ext = filename.split('.').pop();
    if(ext == filename) return "";
    return ext;
}

8
return (ext === nazwa pliku)? '': ext;
Michiel

13
var extension = fileName.substring(fileName.lastIndexOf('.')+1);


8
function file_get_ext(filename)
    {
    return typeof filename != "undefined" ? filename.substring(filename.lastIndexOf(".")+1, filename.length).toLowerCase() : false;
    }

8

Kod

/**
 * Extract file extension from URL.
 * @param {String} url
 * @returns {String} File extension or empty string if no extension is present.
 */
var getFileExtension = function (url) {
    "use strict";
    if (url === null) {
        return "";
    }
    var index = url.lastIndexOf("/");
    if (index !== -1) {
        url = url.substring(index + 1); // Keep path without its segments
    }
    index = url.indexOf("?");
    if (index !== -1) {
        url = url.substring(0, index); // Remove query
    }
    index = url.indexOf("#");
    if (index !== -1) {
        url = url.substring(0, index); // Remove fragment
    }
    index = url.lastIndexOf(".");
    return index !== -1
        ? url.substring(index + 1) // Only keep file extension
        : ""; // No extension found
};

Test

Zauważ, że przy braku zapytania fragment może być nadal obecny.

"https://www.example.com:8080/segment1/segment2/page.html?foo=bar#fragment" --> "html"
"https://www.example.com:8080/segment1/segment2/page.html#fragment"         --> "html"
"https://www.example.com:8080/segment1/segment2/.htaccess?foo=bar#fragment" --> "htaccess"
"https://www.example.com:8080/segment1/segment2/page?foo=bar#fragment"      --> ""
"https://www.example.com:8080/segment1/segment2/?foo=bar#fragment"          --> ""
""                                                                          --> ""
null                                                                        --> ""
"a.b.c.d"                                                                   --> "d"
".a.b"                                                                      --> "b"
".a.b."                                                                     --> ""
"a...b"                                                                     --> "b"
"..."                                                                       --> ""

JSLint

0 Ostrzeżenia.


7

Szybki i działa poprawnie ze ścieżkami

(filename.match(/[^\\\/]\.([^.\\\/]+)$/) || [null]).pop()

Niektóre przypadki krawędzi

/path/.htaccess => null
/dir.with.dot/file => null

Rozwiązania korzystające z podziału są wolne, a rozwiązania z lastIndexOf nie obsługują przypadków skrajnych.


Co masz na myśli? Proszę odnieść się do mojego rozwiązania tutaj: stackoverflow.com/a/12900504/1249581 . Działa dobrze we wszystkich przypadkach i znacznie szybciej niż jakikolwiek inny wyrażenie regularne.
VisioN

Wymieniłem już skrajne przypadki. Twoje rozwiązanie NIE obsługuje ich poprawnie. Jak już napisałem, spróbuj „/dir.with.dot/file”. Twój kod zwraca „kropkę / plik”, co jest absurdalnie nieprawidłowe.
mrbrdo

1
Nikt nie zażądał parsowania ścieżki. Pytanie dotyczyło wyodrębnienia rozszerzeń z nazw plików.
VisioN

3
Jak już mówiłem, nigdy nie zostało to wyraźnie powiedziane, a rozwiązanie, które obsługuje ścieżki, jest oczywiście o wiele bardziej przydatne. Odpowiedź na pytanie dotyczące SO powinna być użyteczna dla innych osób oprócz osoby, która zadała pytanie. Naprawdę nie sądzę, że rozwiązanie, które obsługuje zestaw danych wejściowych, powinno zostać poddane ocenie.
mrbrdo

3
Głosowanie dotyczyło użycia zmiennej globalnej z .exec(). Twój kod będzie lepszy jako (filename.match(/[^\\/]\.([^\\/.]+)$/) || [null]).pop().
VisioN

6

po prostu chciałem się tym podzielić.

fileName.slice(fileName.lastIndexOf('.'))

chociaż ma to wadę, że pliki bez rozszerzenia zwracają ostatni ciąg. ale jeśli to zrobisz, naprawi to wszystko:

   function getExtention(fileName){
     var i = fileName.lastIndexOf('.');
     if(i === -1 ) return false;
     return fileName.slice(i)
   }

O ile pamiętam slicemetoda odnosi się raczej do tablic niż do łańcuchów. Dla ciągów znaków substrlub substringbędzie działać.
VisioN

@VisioN, ale myślę, że powinieneś wiedzieć, że istnieje String.prototype.slicei Array.prototype.slicetak, że to działa w obie strony, rodzaj metody
Hussein Nazzal

1
O tak. Masz rację. Całkowicie zapomniałem o tej metodzie. Mój błąd.
VisioN

5

Jestem pewien, że ktoś może i będzie minimalizować i / lub optymalizować mój kod w przyszłości. Ale na razie mam 200% pewności, że mój kod działa w każdej wyjątkowej sytuacji (np. Tylko z samą nazwą pliku , z względnymi , zależnymi od katalogu głównego i bezwzględnymi adresami URL, z tagami fragmentów # , ciągami zapytań ? i cokolwiek innego w przeciwnym razie możesz rzucić na nią), bezbłędnie i precyzyjnie.

Aby uzyskać dowód, odwiedź: https://projects.jamesandersonjr.com/web/js_projects/get_file_extension_test.php

Oto JSFiddle: https://jsfiddle.net/JamesAndersonJr/ffcdd5z3/

Nie jestem zbyt pewny siebie, ani nie wydmuchuję własnej trąby, ale nie widziałem żadnego bloku kodu dla tego zadania (znajdowanie „poprawnego” rozszerzenia pliku, pośród baterii różnych functionargumentów wejściowych), który działa tak dobrze, jak to.

Uwaga: Z założenia, jeśli rozszerzenie pliku nie istnieje dla podanego ciągu wejściowego, po prostu zwraca pusty ciąg "", nie błąd ani komunikat o błędzie.

Wymaga dwóch argumentów:

  • Łańcuch: fileNameOrURL (oczywisty)

  • Boolean: showUnixDotFiles (Określa, czy pliki zaczynają się od kropki „.”)

Uwaga (2): Jeśli podoba ci się mój kod, pamiętaj o dodaniu go do biblioteki i repozytoriów twojej biblioteki js, ponieważ ciężko pracowałem nad jej udoskonaleniem, a szkoda byłoby marnować ją. Więc bez zbędnych ceregieli, oto:

function getFileExtension(fileNameOrURL, showUnixDotFiles)
    {
        /* First, let's declare some preliminary variables we'll need later on. */
        var fileName;
        var fileExt;

        /* Now we'll create a hidden anchor ('a') element (Note: No need to append this element to the document). */
        var hiddenLink = document.createElement('a');

        /* Just for fun, we'll add a CSS attribute of [ style.display = "none" ]. Remember: You can never be too sure! */
        hiddenLink.style.display = "none";

        /* Set the 'href' attribute of the hidden link we just created, to the 'fileNameOrURL' argument received by this function. */
        hiddenLink.setAttribute('href', fileNameOrURL);

        /* Now, let's take advantage of the browser's built-in parser, to remove elements from the original 'fileNameOrURL' argument received by this function, without actually modifying our newly created hidden 'anchor' element.*/ 
        fileNameOrURL = fileNameOrURL.replace(hiddenLink.protocol, ""); /* First, let's strip out the protocol, if there is one. */
        fileNameOrURL = fileNameOrURL.replace(hiddenLink.hostname, ""); /* Now, we'll strip out the host-name (i.e. domain-name) if there is one. */
        fileNameOrURL = fileNameOrURL.replace(":" + hiddenLink.port, ""); /* Now finally, we'll strip out the port number, if there is one (Kinda overkill though ;-)). */  

        /* Now, we're ready to finish processing the 'fileNameOrURL' variable by removing unnecessary parts, to isolate the file name. */

        /* Operations for working with [relative, root-relative, and absolute] URL's ONLY [BEGIN] */ 

        /* Break the possible URL at the [ '?' ] and take first part, to shave of the entire query string ( everything after the '?'), if it exist. */
        fileNameOrURL = fileNameOrURL.split('?')[0];

        /* Sometimes URL's don't have query's, but DO have a fragment [ # ](i.e 'reference anchor'), so we should also do the same for the fragment tag [ # ]. */
        fileNameOrURL = fileNameOrURL.split('#')[0];

        /* Now that we have just the URL 'ALONE', Let's remove everything to the last slash in URL, to isolate the file name. */
        fileNameOrURL = fileNameOrURL.substr(1 + fileNameOrURL.lastIndexOf("/"));

        /* Operations for working with [relative, root-relative, and absolute] URL's ONLY [END] */ 

        /* Now, 'fileNameOrURL' should just be 'fileName' */
        fileName = fileNameOrURL;

        /* Now, we check if we should show UNIX dot-files, or not. This should be either 'true' or 'false'. */  
        if ( showUnixDotFiles == false )
            {
                /* If not ('false'), we should check if the filename starts with a period (indicating it's a UNIX dot-file). */
                if ( fileName.startsWith(".") )
                    {
                        /* If so, we return a blank string to the function caller. Our job here, is done! */
                        return "";
                    };
            };

        /* Now, let's get everything after the period in the filename (i.e. the correct 'file extension'). */
        fileExt = fileName.substr(1 + fileName.lastIndexOf("."));

        /* Now that we've discovered the correct file extension, let's return it to the function caller. */
        return fileExt;
    };

Cieszyć się! Jesteś bardzo mile widziany!:


1
Niesamowite. Dzięki!
GollyJer

5

// 获取文件后缀名
function getFileExtension(file) {
  var regexp = /\.([0-9a-z]+)(?:[\?#]|$)/i;
  var extension = file.match(regexp);
  return extension && extension[1];
}

console.log(getFileExtension("https://www.example.com:8080/path/name/foo"));
console.log(getFileExtension("https://www.example.com:8080/path/name/foo.BAR"));
console.log(getFileExtension("https://www.example.com:8080/path/name/.quz/foo.bar?key=value#fragment"));
console.log(getFileExtension("https://www.example.com:8080/path/name/.quz.bar?key=value#fragment"));


5

Jeśli masz do czynienia z adresami URL, możesz użyć:

function getExt(filepath){
     return filepath.split("?")[0].split("#")[0].split('.').pop();
}

getExt("../js/logic.v2.min.js") // js
getExt("http://example.net/site/page.php?id=16548") // php
getExt("http://example.net/site/page.html#welcome.to.me") // html
getExt("c:\\logs\\yesterday.log"); // log

Demo: https://jsfiddle.net/squadjot/q5ard4fj/


Naprawdę podoba mi się twoje rozwiązanie. Tak mało robi z tak małą ilością. Użyję tego.
Jules Manson

4

Spróbuj tego:

function getFileExtension(filename) {
  var fileinput = document.getElementById(filename);
  if (!fileinput)
    return "";
  var filename = fileinput.value;
  if (filename.length == 0)
    return "";
  var dot = filename.lastIndexOf(".");
  if (dot == -1)
    return "";
  var extension = filename.substr(dot, filename.length);
  return extension;
}

3
return filename.replace(/\.([a-zA-Z0-9]+)$/, "$1");

edit: Dziwnie (a może nie) $1drugi argument metody replace nie wydaje się działać ... Przepraszam.


1
Działa idealnie, ale przegapiłeś, że będziesz musiał usunąć całą pozostałą treść ciągu: return filename.replace (/^.*? \. ([A-zA-Z0-9] +) $ /, „1 USD”);
roenving 10.10.08

3

Właśnie zdałem sobie sprawę, że nie wystarczy skomentować odpowiedź p4bl0, chociaż odpowiedź Toma wyraźnie rozwiązuje problem:

return filename.replace(/^.*?\.([a-zA-Z0-9]+)$/, "$1");

3

W przypadku większości aplikacji prosty skrypt, taki jak

return /[^.]+$/.exec(filename);

działałoby dobrze (jak zapewnia Tom). Nie jest to jednak głupi dowód. Nie działa, jeśli podano następującą nazwę pliku:

image.jpg?foo=bar

Może to być trochę przesada, ale sugeruję użycie parsera URL, takiego jak ten, aby uniknąć niepowodzenia z powodu nieprzewidzianych nazw plików.

Korzystając z tej konkretnej funkcji, możesz uzyskać nazwę pliku w następujący sposób:

var trueFileName = parse_url('image.jpg?foo=bar').file;

Spowoduje to wygenerowanie pliku „image.jpg” bez zmiennych adresu URL. Następnie możesz pobrać rozszerzenie pliku.


3
function func() {
  var val = document.frm.filename.value;
  var arr = val.split(".");
  alert(arr[arr.length - 1]);
  var arr1 = val.split("\\");
  alert(arr1[arr1.length - 2]);
  if (arr[1] == "gif" || arr[1] == "bmp" || arr[1] == "jpeg") {
    alert("this is an image file ");
  } else {
    alert("this is not an image file");
  }
}

3
function extension(fname) {
  var pos = fname.lastIndexOf(".");
  var strlen = fname.length;
  if (pos != -1 && strlen != pos + 1) {
    var ext = fname.split(".");
    var len = ext.length;
    var extension = ext[len - 1].toLowerCase();
  } else {
    extension = "No extension found";
  }
  return extension;
}

//stosowanie

rozszerzenie („file.jpeg”)

zawsze zwraca rozszerzenie dolne cas, dzięki czemu można sprawdzić, czy zmiana pola działa dla:

plik.JpEg

plik (bez rozszerzenia)

plik. (bez rozszerzenia)


3

Jeśli szukasz określonego rozszerzenia i znasz jego długość, możesz użyć substr :

var file1 = "50.xsl";

if (file1.substr(-4) == '.xsl') {
  // do something
}

Dokumentacja JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr


1
Piękno przychodzi z prostotą. To najmądrzejsza, bardziej elegancka i wydajniejsza odpowiedź ze wszystkich. Zawsze korzystałem z String.substr (-3) lub String.substr (-4), aby pobrać rozszerzenia w systemach Windows. Dlaczego ktoś miałby do tego używać wyrażeń regularnych i zwariowanych pętli.
asiby

13
@asiby Tego rodzaju rozwiązania są głównym powodem awarii rakiet kosmicznych po uruchomieniu.
VisioN

3

Jestem dużo księżyców spóźnionych na przyjęcie, ale dla uproszczenia używam czegoś takiego

var fileName = "I.Am.FileName.docx";
var nameLen = fileName.length;
var lastDotPos = fileName.lastIndexOf(".");
var fileNameSub = false;
if(lastDotPos === -1)
{
    fileNameSub = false;
}
else
{
    //Remove +1 if you want the "." left too
    fileNameSub = fileName.substr(lastDotPos + 1, nameLen);
}
document.getElementById("showInMe").innerHTML = fileNameSub;
<div id="showInMe"></div>


3

W pathmodule znajduje się standardowa funkcja biblioteki :

import path from 'path';

console.log(path.extname('abc.txt'));

Wynik:

.tekst

Jeśli chcesz tylko format:

path.extname('abc.txt').slice(1) // 'txt'

Jeśli nie ma rozszerzenia, funkcja zwróci pusty ciąg znaków:

path.extname('abc') // ''

Jeśli używasz Węzła, pathjest on wbudowany. Jeśli celujesz w przeglądarkę, Webpack spakuje pathdla ciebie implementację. Jeśli celujesz w przeglądarkę bez pakietu Webpack, możesz dołączyć przeglądanie ścieżek ręcznie .

Nie ma powodu do dzielenia ciągów ani wyrażeń regularnych.


Kto powiedział coś o węźle?
Shannon Hochkins,

Twój argument za nie stosując podział lub wyrażeń regularnych jest to plugin lub pakiet aplikacji z węzłem, to jest nad górną odpowiedzią na służebnej zadanie
Shannon Hochkins

@ShannonHochkins przez większość czasu i tak masz te ustawienia
sdgfsdh

@AndreiDraganescu Nie zamierzałem tego robić protekcjonalnie, więc go stonowałem.
sdgfsdh

3

„one-liner”, aby uzyskać nazwę pliku i rozszerzenie reduceoraz zniszczenie tablicy :

var str = "filename.with_dot.png";
var [filename, extension] = str.split('.').reduce((acc, val, i, arr) => (i == arr.length - 1) ? [acc[0].substring(1), val] : [[acc[0], val].join('.')], [])

console.log({filename, extension});

z lepszym wcięciem:

var str = "filename.with_dot.png";
var [filename, extension] = str.split('.')
   .reduce((acc, val, i, arr) => (i == arr.length - 1) 
       ? [acc[0].substring(1), val] 
       : [[acc[0], val].join('.')], [])


console.log({filename, extension});

// {
//   "filename": "filename.with_dot",
//   "extension": "png"
// }

To nie działa w IE 11
Gokul Maha

Możesz użyć babel / maszynopis / polyfill do brakujących funkcji ES7 + w IE 11
boehm_s

2

Jednowierszowe rozwiązanie, które uwzględni również parametry zapytania i wszelkie znaki w adresie URL.

string.match(/(.*)\??/i).shift().replace(/\?.*/, '').split('.').pop()

// Example
// some.url.com/with.in/&ot.s/files/file.jpg?spec=1&.ext=jpg
// jpg

(1) Jeśli plik nie ma rozszerzenia, nadal zwróci nazwę pliku. (2) Jeśli w adresie URL jest fragment, ale nie ma zapytania (np. page.html#fragment), To zwróci rozszerzenie pliku i fragment.
Jack

2

To proste rozwiązanie

function extension(filename) {
  var r = /.+\.(.+)$/.exec(filename);
  return r ? r[1] : null;
}

Testy

/* tests */
test('cat.gif', 'gif');
test('main.c', 'c');
test('file.with.multiple.dots.zip', 'zip');
test('.htaccess', null);
test('noextension.', null);
test('noextension', null);
test('', null);

// test utility function
function test(input, expect) {
  var result = extension(input);
  if (result === expect)
    console.log(result, input);
  else
    console.error(result, input);
}

function extension(filename) {
  var r = /.+\.(.+)$/.exec(filename);
  return r ? r[1] : null;
}


1

Odpowiedź Wallacera jest dobra, ale potrzebna jest jeszcze jedna kontrola.

Jeśli plik nie ma rozszerzenia, użyje nazwy pliku jako rozszerzenia, co nie jest dobre.

Spróbuj tego:

return ( filename.indexOf('.') > 0 ) ? filename.split('.').pop().toLowerCase() : 'undefined';

1

Nie zapominaj, że niektóre pliki nie mogą mieć rozszerzenia, więc:

var parts = filename.split('.');
return (parts.length > 1) ? parts.pop() : '';

1
var file = "hello.txt";
var ext = (function(file, lio) { 
  return lio === -1 ? undefined : file.substring(lio+1); 
})(file, file.lastIndexOf("."));

// hello.txt -> txt
// hello.dolly.txt -> txt
// hello -> undefined
// .hello -> hello

1
fetchFileExtention(fileName) {
    return fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2);
}

2
Ten fragment kodu może rozwiązać pytanie, ale wyjaśnienie naprawdę pomaga poprawić jakość posta. Pamiętaj, że w przyszłości odpowiadasz na pytanie czytelników, a ci ludzie mogą nie znać przyczyn Twojej sugestii kodu.
Brett DeWoody
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.