717 Stimmen

Wie kann ich Dateierweiterungen mit JavaScript erhalten?

Siehe Code:

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

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

1139voto

Tom Punkte 5825

Neuere Bearbeitung: Vieles hat sich geändert, seit diese Frage zum ersten Mal gestellt wurde - es gibt eine Menge wirklich guter Informationen in wallacers überarbeitete Antwort wie auch Die hervorragende Aufschlüsselung von VisioN


Edit : Nur weil dies die akzeptierte Antwort ist; wallacer's Antwort ist in der Tat viel besser:

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

Meine alte Antwort:

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

Sie sollten es tun.

Edit : Als Antwort auf den Kommentar von PhiLho, verwenden Sie etwas wie:

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

4 Stimmen

Ist es nicht teuer, die Regex zweimal auszuführen?

0 Stimmen

Ist es besser, stattdessen regex als die letzteindexof verwenden? danke.

7 Stimmen

Die hoch bewertete Antwort unten ist viel besser.

1092voto

wallacer Punkte 11945
return filename.split('.').pop();

Edit :

Dies ist eine weitere Nicht-Regex-Lösung, die meiner Meinung nach effizienter ist:

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

Es gibt einige Eckfälle, die sich besser mit VisioNs Antwort unten, insbesondere Dateien ohne Erweiterung ( .htaccess etc. enthalten).

Es ist sehr performant und behandelt Eckfälle auf eine wohl bessere Weise, indem es "" anstelle der vollständigen Zeichenfolge, wenn kein Punkt oder keine Zeichenfolge vor dem Punkt vorhanden ist. Es ist eine sehr gut ausgearbeitete Lösung, wenn auch schwer zu lesen. Fügen Sie es in Ihre Helfer Lib und verwenden Sie es einfach.

Alte Bearbeitung:

Eine sicherere Implementierung, wenn Sie auf Dateien ohne Erweiterung oder versteckte Dateien ohne Erweiterung stoßen (siehe VisioNs Kommentar zu Toms Antwort oben), wäre etwas in dieser Art

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

Si a.length eine ist, handelt es sich um eine sichtbare Datei ohne Erweiterung, d.h. Datei

Si a[0] === "" y a.length === 2 es ist eine versteckte Datei ohne Erweiterung, d.h.. .htaccess

Damit sollten die Probleme mit den etwas komplexeren Fällen behoben sein. In Bezug auf die Leistung ist diese Lösung meiner Meinung nach ein wenig langsamer als regex in den meisten Browsern. Für die meisten üblichen Zwecke sollte dieser Code jedoch vollkommen brauchbar sein.

4 Stimmen

Ich kann mich nicht zur Leistung äußern, aber dieser hier sieht wirklich sauber aus! Ich benutze es. +1

7 Stimmen

Aber in diesem Fall sieht der Dateiname wie filname.tes.test.jpg aus. Bitte betrachten Sie die Ausgabe. Ich hoffe, sie ist falsch.

22 Stimmen

In diesem Fall lautet die Ausgabe "jpg".

387voto

VisioN Punkte 137670

Die folgende Lösung lautet schnell y kurz genug, um sie bei Massenoperationen zu verwenden und zusätzliche Bytes zu sparen:

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

Hier ist eine weitere einzeilige universelle Lösung ohne Regexp:

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

Beide funktionieren korrekt mit Namen ohne Endung (z. B. myfile ) oder beginnend mit . Punkt (z.B. .htaccess ) :

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

Wenn Sie Wert auf die Geschwindigkeit legen, können Sie die Benchmark und prüfen Sie, ob die angebotenen Lösungen die schnellsten sind, während die kurze Lösung enorm schnell ist:

Speed comparison

So funktioniert die kurze Version:

  1. String.lastIndexOf Methode gibt die letzte Position der Teilzeichenkette zurück (d. h. "." ) in der angegebenen Zeichenkette (d. h. fname ). Wenn die Teilzeichenkette nicht gefunden wird, gibt die Methode -1 .
  2. Die "inakzeptablen" Positionen des Punktes im Dateinamen sind -1 y 0 , die sich jeweils auf Namen ohne Endung beziehen (z. B. "name" ) und auf Namen, die mit einem Punkt beginnen (z. B. ".htaccess" ).
  3. Null-Füllung Rechtsverschiebung Operator ( >>> ), wenn sie mit Null verwendet wird, wirkt sich auf die Umwandlung negativer Zahlen aus -1 a 4294967295 y -2 a 4294967294 was nützlich ist, um den Dateinamen in den Randfällen unverändert zu lassen (eine Art Trick hier).
  4. String.prototype.slice extrahiert den Teil des Dateinamens aus der Position, der wie beschrieben berechnet wurde. Wenn die Positionsnummer größer ist als die Länge der Zeichenkette, gibt die Methode "" .

Wenn Sie eine klarere Lösung wünschen, die auf die gleiche Weise funktioniert (und zusätzlich den vollen Pfad unterstützt), sollten Sie sich die folgende erweiterte Version ansehen. Diese Lösung wird Langsamer als frühere Einzeiler, ist aber viel leichter zu verstehen.

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"

Alle drei Varianten sollten in jedem Webbrowser auf der Client-Seite funktionieren und können auch im serverseitigen NodeJS-Code verwendet werden.

0 Stimmen

@Zipp Um es verständlicher zu machen, habe ich die Beschreibung des Ansatzes und den Geschwindigkeitsvergleich hinzugefügt, um zu zeigen, wie schnell die Lösung ist.

0 Stimmen

"fname.substr((~-fname.lastIndexOf(".")) >>> 0) + 2)" ergibt einen falschen Wert für ".htaccess".

0 Stimmen

@BennyNeugebauer Was ist in Ihrem Fall falsch? Es gibt "" da Dateinamen, die mit einem Punkt beginnen (wie .htaccess o .htpasswd ) hat keine Erweiterung.

42voto

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

Getestet mit

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

Aussi

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

0 Stimmen

Damit es im IE funktioniert: var pattern = "^.+ \\. ([^.]+)$"; var ext = new RegExp(pattern);

34voto

sdgfsdh Punkte 28371

Es gibt eine Standardbibliotheksfunktion für diesen Zweck in der Datei path Modul:

import path from 'path';

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

Output:

.txt

Wenn Sie also nur das Format wollen:

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

Wenn keine Erweiterung vorhanden ist, gibt die Funktion eine leere Zeichenkette zurück:

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

Wenn Sie Node verwenden, dann path ist eingebaut. Wenn Sie auf den Browser abzielen, dann bündelt Webpack eine path Umsetzung für Sie. Wenn Sie auf den Browser ohne Webpack abzielen, dann können Sie path-browserify manuell.

Es gibt keinen Grund für die Aufteilung von Strings oder Regex.

4 Stimmen

Wer hat etwas von einem Knotenpunkt gesagt?

0 Stimmen

Ihr Argument für die Nichtverwendung von Splitting oder regulären Ausdrücken ist die Einbeziehung von Plugins oder die Bündelung der Anwendung mit Node, es ist eine übertriebene Antwort für eine einfache Aufgabe

1 Stimmen

@ShannonHochkins die meiste Zeit hat man diese Dinge sowieso eingerichtet

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X