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.



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.


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(/\.[^/.]+$/, "")

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.


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];

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);
}

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


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 + ""
}

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('.')


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

Hier ist eine weitere Regex-basierte Lösung:

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

Dies sollte nur das letzte Segment abschneiden.


7

Einfache Sache:

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

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(/(\.[^/.]+)+$/, "");


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);
  


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('.')), '')


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.


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");

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'

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'


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;
}

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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.