Wie schneide ich eine Dateierweiterung aus einem String in JavaScript?

295

Angenommen x = filename.jpg, ich möchte herausfinden filename, wo filenamesich ein beliebiger Dateiname befinden könnte (Nehmen wir an, der Dateiname enthält zur Vereinfachung nur [a-zA-Z0-9-_].).

Ich habe x.substring(0, x.indexOf('.jpg'))auf DZone Snippets gesehen , würde aber nicht x.substring(0, x.length-4)besser abschneiden ? Denn lengthist eine Eigenschaft und führt keine Zeichenprüfung durch, während indexOf()es sich um eine Funktion handelt und eine Zeichenprüfung durchführt.

ma11hew28
quelle
Ziemlich genau wie stackoverflow.com/questions/1991608/… . Und wenn Sie nicht eine Menge davon tun, ist die Sorge um die Effizienz eine vorzeitige Optimierung.
Der archetypische Paul
Im Zeitalter von ES6 sehen Sie auch das Pfad- Modul - falls Sie NodeJS oder eine ordnungsgemäße Transpilation verwenden
Frank Nocke

Antworten:

173

Wenn Sie die Länge der Erweiterung kennen, können Sie verwenden x.slice(0, -4)(wobei 4 die drei Zeichen der Erweiterung und der Punkt sind).

Wenn Sie die Länge nicht kennen, wäre @John Hartsock Regex der richtige Ansatz.

Wenn Sie keine regulären Ausdrücke verwenden möchten, können Sie dies versuchen (weniger performant):

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

Beachten Sie, dass dies bei Dateien ohne Erweiterung fehlschlägt.

Marek Sapota
quelle
Diese Lösung gefällt mir am besten. Es ist sauber und ich kann es verwenden, weil ich weiß, dass die Dateierweiterung immer ist .jpg. Ich habe nach etwas wie Ruby's gesucht x[0..-5]und sehe x.slice(0, -4)toll aus! Vielen Dank! Und vielen Dank an alle anderen für all die anderen robusten Alternativen!
ma11hew28
22
Dies ist nicht die optimale Lösung. Bitte überprüfen Sie andere Lösungen unten.
Bunjeeb
8
Und wenn Sie sich über die Länge der Erweiterung nicht 100% sicher sind, dann nicht: "picture.jpeg".slice(0, -4)-> "Bild".
basic6
13
Dies ist eine gefährliche Lösung, da Sie die Länge des Formats nicht wirklich kennen.
Coder
"Wenn Sie die Länge der Erweiterung kennen" Es ist Jahrzehnte her, seit dies eine akzeptable Annahme war. Benutze das nicht mehr.
Alexander - Monica
453

Ich bin mir nicht sicher, was schneller funktionieren würde, aber dies wäre zuverlässiger, wenn es um Erweiterungen wie .jpegoder geht.html

x.replace(/\.[^/.]+$/, "")
John Hartsock
quelle
15
Sie möchten wahrscheinlich auch / als Pfadtrennzeichen nicht zulassen, daher lautet der reguläre
Ausdruck
Dies funktioniert für jede Länge der Dateierweiterung (.txt oder .html oder .htaccess) und ermöglicht auch, dass der Dateiname zusätzliche Punktzeichen (.) Enthält. Es würde zB .tar.gz nicht verarbeiten, da die Erweiterung selbst einen Punkt enthält. Es ist üblicher, dass ein Dateiname zusätzliche Punkte enthält als eine Dateierweiterung. Vielen Dank!
Steve Seeger
2
@ Vik Es gibt einen Unterschied zwischen der 'richtigen Antwort' und der akzeptierten Antwort. Eine akzeptierte Antwort ist nur die Antwort, die für denjenigen hilfreich war, der die Frage gestellt hat.
Steven
4
Ich nehme an, dass es Probleme mit der Windows-Plattform geben kann, da es zu Schrägstrichen kommen kann. Der reguläre Ausdruck sollte also /\.[^/\\.‹+$/ sein.
Alex Chuev
1
@ ElgsQianChen hier ist ein großartiges Tool für Sie, um Ihre Frage zu beantworten regexr.com
John Hartsock
281

In node.js kann der Name der Datei ohne die Erweiterung wie folgt abgerufen werden.

const path = require('path');
const filename = 'hello.html';

path.parse(filename).name; // hello
path.parse(filename).ext;  // .html

Eine weitere Erklärung auf Node.js Dokumentation Seite.

Jibesh Patra
quelle
2
Worüber Sie sprechen @kaasdude .... Diese Methode entfernt effektiv die Erweiterung auf dem Knoten. Sie sind sich nicht sicher, was Sie ausdrücken möchten, aber diese Methode funktioniert mit Perlen.
Erick
1
Diese Antwort ist ziemlich auf den serverseitigen Knoten beschränkt. Wenn Sie versuchen, dies im Reaktionscode zu verwenden, scheint es nicht zu importieren.
Charlie
1
Wenn Sie eine Erweiterung von einem Pfad einschließlich der Verzeichnisse entfernen möchten, können Sie var parsed = path.parse(filename)von gefolgt path.join(parsed.dir, parsed.name).
Jespertheend
Eine andere Möglichkeit ist let base = path.basename( file_path, path.extname( file_path ) ).
Bicarlsen
116

x.length-4berücksichtigt nur Erweiterungen von 3 Zeichen. Was ist, wenn Sie haben filename.jpegoder filename.pl?

BEARBEITEN:

Um zu antworten ... sicher, wenn Sie immer eine Erweiterung von haben .jpg, x.length-4würde gut funktionieren.

Wenn Sie jedoch die Länge Ihrer Erweiterung nicht kennen, sind verschiedene Lösungen besser / robuster.

x = x.replace(/\..+$/, '');

ODER

x = x.substring(0, x.lastIndexOf('.'));

ODER

x = x.replace(/(.*)\.(.*?)$/, "$1");

ODER (mit der Annahme, dass der Dateiname nur einen Punkt hat)

parts = x.match(/[^\.]+/);
x = parts[0];

ODER (auch mit nur einem Punkt)

parts = x.split(".");
x = parts[0];
Jeff B.
quelle
12
?? Sie können einen Dateinamen haben, z. B.: "Summer.family.jpg". In diesem Fall gibt split ('.') [0] nur einen partiellen Dateinamen zurück. Ich würde diese aus der Antwort entfernen oder unter dem Problem für dieses Beispiel klar angeben. @basarat ...
Roko C. Buljan
Etwas, das ich häufig in Bezug auf var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
Teilesplits mache
x.split (".") sollte nicht einmal als Antwort betrachtet werden. Ich weiß, dass ich ein '.' in fast allen meinen Dateinamenskonventionen, z. B. 'query.controller.js' oder 'my.family.jpg'.
Lee Brindley
@ Lee2808: Daher die Warnung von nur einem Punkt. Dies soll lediglich zeigen, dass es je nach Anwendung eine Reihe von Ansätzen gibt. Ich würde sicherlich in fast allen Fällen eine der anderen Methoden anwenden.
Jeff B
x = x.substr(0, x.lastIndexOf('.'));- Du meintest wahrscheinlich x = x.substring(0, x.lastIndexOf('.'));?
Dziad Borowy
39

Sie können möglicherweise davon ausgehen, dass der letzte Punkt das Erweiterungsbegrenzer ist.

var x = 'filename.jpg';
var f = x.substr(0, x.lastIndexOf('.'));

Wenn die Datei keine Erweiterung hat, wird eine leere Zeichenfolge zurückgegeben. Um dies zu beheben, verwenden Sie diese Funktion

function removeExtension(filename){
    var lastDotPosition = filename.lastIndexOf(".");
    if (lastDotPosition === -1) return filename;
    else return filename.substr(0, lastDotPosition);
}
Martin Algesten
quelle
Warnung, dies schlägt fehl, wenn zufällig keine Dateinamenerweiterung vorhanden ist. Du hast eine leere Schnur übrig.
Brad
18
Kürzere Version, die keine Punkte berücksichtigt. var f = x.substr(0, x.lastIndexOf('.')) || x;Dies funktioniert, weil eine leere Zeichenfolge falsch ist und daher x zurückgibt.
Jonathan Rowny
22

Ich mag dieses, weil es ein Einzeiler ist, der nicht zu schwer zu lesen ist:

filename.substring(0, filename.lastIndexOf('.')) || filename
Jakubiszon
quelle
17

In Node.js-Versionen vor 0.12.x:

path.basename(filename, path.extname(filename))

Natürlich funktioniert dies auch in 0.12.x und höher.

blah238
quelle
Die path.parseAntwort ist einfacher.
Dan Dascalescu
12

Dies funktioniert auch dann, wenn das Trennzeichen nicht in der Zeichenfolge vorhanden ist.

String.prototype.beforeLastIndex = function (delimiter) {
    return this.split(delimiter).slice(0,-1).join(delimiter) || this + ""
}

"image".beforeLastIndex(".") // "image"
"image.jpeg".beforeLastIndex(".") // "image"
"image.second.jpeg".beforeLastIndex(".") // "image.second"
"image.second.third.jpeg".beforeLastIndex(".") // "image.second.third"

Kann auch wie folgt als Einzeiler verwendet werden:

var filename = "this.is.a.filename.txt";
console.log(filename.split(".").slice(0,-1).join(".") || filename + "");

EDIT: Dies ist eine effizientere Lösung:

String.prototype.beforeLastIndex = function (delimiter) {
    return this.substr(0,this.lastIndexOf(delimiter)) || this + ""
}
Andrew Plank
quelle
10

Ich weiß nicht, ob es eine gültige Option ist, aber ich benutze diese:

name = filename.split(".");
// trimming with pop()
name.pop();
// getting the name with join()
name.join('.'); // we split by '.' and we join by '.' to restore other eventual points.

Es ist nicht nur eine Operation, die ich kenne, aber zumindest sollte sie immer funktionieren!

UPDATE: Wenn Sie einen Oneliner möchten, sind Sie hier:

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

Giacomo Cerquone
quelle
1
Es sollte nicht name.join ('') sein, sondern name.join ('.'). Sie teilen sich nach Punkten, verbinden sich aber durch Komma und hello.name.txtkehren zurückhello, name
Evil
7

Ein weiterer Einzeiler:

x.split(".").slice(0, -1).join(".")
Jacob Bundgaard
quelle
7

Hier ist eine weitere Regex-basierte Lösung:

filename.replace(/\.[^.$]+$/, '');

Dies sollte nur das letzte Segment abschneiden.

Chad Johnson
quelle
7

Einfache Sache:

var n = str.lastIndexOf(".");
return n > -1 ? str.substr(0, n) : str;
Dugh
quelle
6

Die akzeptierte Antwort entfernt nur den letzten Erweiterungsteil ( .jpeg), was in den meisten Fällen eine gute Wahl sein kann.

Ich musste einmal alle Erweiterungen entfernen ( .tar.gz) und die Dateinamen waren darauf beschränkt, keine Punkte zu enthalten ( 2015-01-01.backup.tarwäre also kein Problem):

var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");
basic6
quelle
4
var fileName = "something.extension";
fileName.slice(0, -path.extname(fileName).length) // === "something"
Ja
quelle
Dies ist die einzige Methode, die bisher für vollständige Pfade funktioniert: path/name.ext-> paht/nameanstatt nur zurückzukehren name, aber ich würde es lieber damit machen, fs.parseobwohl es etwas ausführlicher ist: stackoverflow.com/a/59576950/895245
Ciro Santilli 郝海东 冠状 病六四 事件 法轮功
3

Wenn Sie eine Variable verarbeiten müssen, die den vollständigen Pfad enthält (Beispiel:) thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg"und nur "Dateiname" zurückgeben möchten, können Sie Folgendes verwenden:

theName = thePath.split("/").slice(-1).join().split(".").shift();

das Ergebnis ist theName == "filename" ;

Um es zu versuchen, schreiben Sie den folgenden Befehl in das Konsolenfenster Ihres Chrome-Debuggers: window.location.pathname.split("/").slice(-1).join().split(".").shift()

Wenn Sie nur den Dateinamen und seine Erweiterung (z. B. :) verarbeiten müssen theNameWithExt = "filename.jpg":

theName = theNameWithExt.split(".").shift();

das Ergebnis ist der Name == "Dateiname" , wie oben;

Anmerkungen:

  1. Die erste ist etwas langsamer, da mehr Operationen ausgeführt werden. funktioniert aber in beiden Fällen, mit anderen Worten, es kann den Dateinamen ohne Erweiterung aus einer bestimmten Zeichenfolge extrahieren, die einen Pfad oder einen Dateinamen mit ex enthält. Die zweite funktioniert zwar nur, wenn die angegebene Variable einen Dateinamen mit ext wie filename.ext enthält, ist aber etwas schneller.
  2. Beide Lösungen funktionieren sowohl für lokale als auch für Serverdateien.

Aber ich kann weder über den Leistungsvergleich mit anderen Antworten noch über die Browser- oder Betriebssystemkompatibilität etwas sagen.

Arbeitsausschnitt 1: Der vollständige Pfad

var thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg";
theName = thePath.split("/").slice(-1).join().split(".").shift();
alert(theName);
  

Arbeitsausschnitt 2: Der Dateiname mit der Erweiterung

var theNameWithExt = "filename.jpg";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
  

Arbeitsausschnitt 2: Der Dateiname mit doppelter Erweiterung

var theNameWithExt = "filename.tar.gz";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
  

willy wonka
quelle
3

Obwohl es ziemlich spät ist, werde ich einen weiteren Ansatz hinzufügen, um den Dateinamen ohne Erweiterung mit einfachen alten JS- zu erhalten.

path.replace(path.substr(path.lastIndexOf('.')), '')

Munim Dibosh
quelle
oder path.split('.').pop()für ein Teil Dateierweiterungen
mixdev
Er versuchte tatsächlich, den Dateinamen zu bekommen, nicht die Erweiterung!
Munim Dibosh
3

Node.js entfernt die Erweiterung aus dem vollständigen Pfadverwaltungsverzeichnis

https://stackoverflow.com/a/31615711/895245 zum Beispiel hat path/hello.html-> hello, aber wenn Sie wollen path/hello.html-> path/hello, können Sie dies verwenden:

#!/usr/bin/env node
const path = require('path');
const filename = 'path/hello.html';
const filename_parsed = path.parse(filename);
console.log(path.join(filename_parsed.dir, filename_parsed.name));

gibt auch das Verzeichnis aus:

path/hello

https://stackoverflow.com/a/36099196/895245 erreicht dies ebenfalls, aber ich finde diesen Ansatz etwas semantisch ansprechender.

Getestet in Node.js v10.15.2.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
0

Hier bieten sich reguläre Ausdrücke an! Die .replace()Methode von Javascript verwendet einen regulären Ausdruck, und Sie können diesen verwenden, um das zu erreichen, was Sie wollen:

// assuming var x = filename.jpg or some extension
x = x.replace(/(.*)\.[^.]+$/, "$1");
Alex
quelle
0

Ein weiterer Einzeiler - wir nehmen an, dass unsere Datei ein JPG-Bild ist >> Beispiel: var yourStr = 'test.jpg';

    yourStr = yourStr.slice(0, -4); // 'test'
SorinN
quelle
0

Sie können pathzum Manövrieren verwenden.

var MYPATH = '/User/HELLO/WORLD/FILENAME.js';
var MYEXT = '.js';
var fileName = path.basename(MYPATH, MYEXT);
var filePath = path.dirname(MYPATH) + '/' + fileName;

Ausgabe

> filePath
'/User/HELLO/WORLD/FILENAME'
> fileName
'FILENAME'
> MYPATH
'/User/HELLO/WORLD/FILENAME.js'
Alan Dong
quelle
0
x.slice(0, -(x.split('.').pop().length + 1));
ishandutta2007
quelle
0

Dies ist der Code, mit dem ich die Erweiterung aus einem Dateinamen entferne, ohne entweder Regex oder IndexOf zu verwenden (IndexOf wird in IE8 nicht unterstützt). Es wird davon ausgegangen, dass die Erweiterung ein beliebiger Text nach dem letzten '.' Ist. Charakter.

Es funktioniert für:

  • Dateien ohne Erweiterung: "myletter"
  • Dateien mit '.' im Namen: "my.letter.txt"
  • unbekannte Länge der Dateierweiterung: "my.letter.html"

Hier ist der Code:

var filename = "my.letter.txt" // some filename

var substrings = filename.split('.'); // split the string at '.'
if (substrings.length == 1)
{
  return filename; // there was no file extension, file was something like 'myfile'
}
else
{
  var ext = substrings.pop(); // remove the last element
  var name = substrings.join(""); // rejoin the remaining elements without separator
  name = ([name, ext]).join("."); // readd the extension
  return name;
}
Kleines Gehirn
quelle
schlägt fehl hello.tar.gz, Ausgabe ist hellotar.
Asif Ali
#AsifAli danke du hast recht, ich habe vergessen die Dateierweiterung zu lesen. Ich habe die Antwort aktualisiert, ich hoffe es funktioniert jetzt.
Little Brain
-3

Ich würde so etwas wie x.substring (0, x.lastIndexOf ('.')) Verwenden. Wenn Sie Leistung erbringen möchten, sollten Sie sich überhaupt nicht für Javascript entscheiden :-p Nein, eine weitere Aussage spielt für 99,99999% aller Zwecke keine Rolle.

Lucas Moeskops
quelle
2
"Wenn Sie Leistung erbringen möchten, sollten Sie sich überhaupt nicht für Javascript entscheiden" - Was schlagen Sie noch für Webanwendungen vor?
TJ
Er erwähnt keine Webanwendungen.
Lucas Moeskops
1
Diese Frage wurde gestellt und die Antwort wurde vor 7 Jahren im Jahr 2010 veröffentlicht, und JavaScript wurde so gut wie nur in Webanwendungen verwendet. (Node wurde gerade geboren, es gab zu diesem Zeitpunkt noch nicht einmal einen Führer oder NPM)
TJ
;-) Wenn bei solchen Aufgaben die Leistung eine Rolle spielt, können Sie dies im Backend tun und die Ergebnisse im Frontend verarbeiten.
Lucas Moeskops