Come tagliare un'estensione di file da una stringa in JavaScript?


295

Ad esempio, supponendo che x = filename.jpg, voglio ottenere filename, dove filenamepotrebbe essere qualsiasi nome di file (supponiamo che il nome del file contenga solo [a-zA-Z0-9-_] per semplificare.).

Ho visto x.substring(0, x.indexOf('.jpg'))su frammenti di DZone , ma non avrebbe x.substring(0, x.length-4)funzionato meglio? Perché, lengthè una proprietà e non esegue il controllo dei caratteri mentre indexOf()è una funzione e fa il controllo dei caratteri.



Praticamente uguale a stackoverflow.com/questions/1991608/… . E a meno che tu non ne dia un gran numero di questi, preoccuparsi dell'efficienza è l'ottimizzazione precoce.
L'archetipo Paolo,

Nell'era di ES6, vedi anche il modulo Path - nel caso in cui tu stia usando nodejs o una corretta traduzione
Frank Nocke,

Risposte:


173

Se conosci la lunghezza dell'estensione, puoi usare x.slice(0, -4)(dove 4 sono i tre caratteri dell'estensione e del punto).

Se non conosci la lunghezza di @John Hartsock regex sarebbe l'approccio giusto.

Se preferisci non usare espressioni regolari, puoi provare questo (meno performante):

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

Nota che fallirà sui file senza estensione.


Mi piace questa soluzione al meglio. È pulito e posso usarlo perché so che l'estensione del file è sempre .jpg. Stavo cercando qualcosa come Ruby x[0..-5], e x.slice(0, -4)sembra fantastico! Grazie! E grazie a tutti gli altri per tutte le altre solide alternative fornite!
ma11hew28,

22
questa non è la soluzione ottimale, controlla altre soluzioni di seguito.
bunjeeb,

8
E se non sei sicuro al 100% della lunghezza dell'estensione, non farlo: "picture.jpeg".slice(0, -4)-> "immagine".
basic6

13
Questa è una soluzione pericolosa, perché non conosci davvero la lunghezza del formato.
Coder

"Se conosci la lunghezza dell'estensione" Sono passati decenni da quando questo era un presupposto accettabile da fare. Non usarlo più.
Alexander - Ripristina Monica il

453

Non sono sicuro di cosa potrebbe funzionare più velocemente, ma questo sarebbe più affidabile quando si tratta di estensione come .jpego.html

x.replace(/\.[^/.]+$/, "")

15
Probabilmente vuoi anche disabilitare / come separatore di percorso, quindi la regexp è /\
[

Funziona per qualsiasi lunghezza dell'estensione del file (.txt o .html o .htaccess) e consente anche al nome del file di contenere caratteri punto (.) Aggiuntivi. Non gestirà ad esempio .tar.gz a causa dell'estensione stessa contenente un punto. È più comune che un nome file contenga periodi aggiuntivi rispetto a un'estensione di file. Grazie!
Steve Seeger,

2
@Vik C'è una differenza tra la "risposta giusta" e la risposta accettata. Una risposta accettata è solo la risposta che è stata utile per chi ha posto la domanda.
Steven,

4
Suppongo che potrebbero esserci problemi con la piattaforma Windows perché potrebbero esserci delle barre rovesciate. Quindi il regexp dovrebbe essere /\ .[^/\\.[+$/.
Alex Chuev il

1
@ElgsQianChen ecco un ottimo strumento per aiutarti a rispondere alla tua domanda regexr.com
John Hartsock

281

In node.js , il nome del file senza l'estensione può essere ottenuto come segue.

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

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

Ulteriori spiegazioni alla pagina della documentazione di Node.js.


2
Di cosa stai parlando @kaasdude .... questo metodo rimuove efficacemente l'estensione sul nodo., Non sono sicuro di ciò che volevi esprimere, ma questo metodo funziona perle.
Erick,

1
Questa risposta è piuttosto limitata al nodo lato server. Se si tenta di utilizzare questo nel codice di reazione, non sembra importare.
Charlie

1
se si desidera rimuovere un'estensione da un percorso comprese le directory, è possibile farlo var parsed = path.parse(filename)seguito da path.join(parsed.dir, parsed.name).
Jespertheend,

Un'altra possibilità è let base = path.basename( file_path, path.extname( file_path ) ).
Bicarlsen,

116

x.length-4rappresenta solo estensioni di 3 caratteri. E se hai filename.jpego filename.pl?

MODIFICARE:

Per rispondere ... certo, se hai sempre un'estensione di .jpg, x.length-4funzionerebbe bene.

Tuttavia, se non conosci la lunghezza della tua estensione, una delle numerose soluzioni è migliore / più robusta.

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

O

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

O

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

OPPURE (con il nome file presupposto ha solo un punto)

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

OPPURE (anche con un solo punto)

parts = x.split(".");
x = parts[0];

12
?? Puoi avere un nome file es: "summer.family.jpg" in tal caso diviso ('.') [0] restituirà solo un nome file parziale. Vorrei rimuovere quello dalla risposta, o dichiarare chiaramente sotto il problema per quell'esempio. @basarat ...
Roko C. Buljan,

Qualcosa che faccio frequentemente riguardo alla suddivisione delle parti:var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
radicand

x.split (".") non dovrebbe nemmeno essere considerato una risposta. So di usare un '.' in quasi tutte le mie convenzioni di denominazione dei file, ad esempio "survey.controller.js" o "my.family.jpg".
Lee Brindley,

@ Lee2808: Da qui l'avvertimento di un solo punto. Questo ha semplicemente lo scopo di mostrare che esistono diversi approcci, a seconda dell'applicazione. Utilizzerei sicuramente uno degli altri metodi in quasi tutti i casi.
Jeff B,

x = x.substr(0, x.lastIndexOf('.'));- probabilmente intendevi x = x.substring(0, x.lastIndexOf('.'));?
Dziad Borowy,

39

Puoi forse usare il presupposto che l'ultimo punto sarà il delimitatore di estensione.

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

Se il file non ha estensione, restituirà una stringa vuota. Per risolvere questo uso questa funzione

function removeExtension(filename){
    var lastDotPosition = filename.lastIndexOf(".");
    if (lastDotPosition === -1) return filename;
    else return filename.substr(0, lastDotPosition);
}

Attenzione, questo non riesce se non si verifica alcuna estensione del nome file. Ti rimane una stringa vuota.
Brad

18
Versione più breve che non rappresenta punti. var f = x.substr(0, x.lastIndexOf('.')) || x;Questo funziona perché una stringa vuota è falsa, quindi restituisce x.
Jonathan Rowny,

22

Mi piace questo perché è una fodera che non è troppo difficile da leggere:

filename.substring(0, filename.lastIndexOf('.')) || filename


12

Funziona anche quando il delimitatore non è presente nella stringa.

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"

Può anche essere usato come un liner in questo modo:

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

EDIT: questa è una soluzione più efficiente:

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

10

Non so se è un'opzione valida ma io uso questo:

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.

Non è solo un'operazione che conosco, ma almeno dovrebbe sempre funzionare!

AGGIORNAMENTO: Se vuoi un oneliner, eccoti qui:

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


1
Non dovrebbe essere name.join ('') ma name.join ('.'). Dividi per punto ma unisci per virgola, quindi hello.name.txtritornahello, name
Evil


7

Ecco un'altra soluzione basata su regex:

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

Questo dovrebbe solo tagliare l'ultimo segmento.


7

Semplice:

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

6

La risposta accettata rimuove solo l'ultima parte dell'estensione ( .jpeg), che potrebbe essere una buona scelta nella maggior parte dei casi.

Una volta ho dovuto rimuovere tutte le estensioni ( .tar.gz) e i nomi dei file erano limitati per non contenere punti (quindi 2015-01-01.backup.tarnon sarebbe un problema):

var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");


3

Se devi elaborare una variabile che contiene il percorso completo (es .:) thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg"e vuoi restituire solo il "nome file" puoi usare:

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

il risultato sarà theName == "nomefile" ;

Per provarlo scrivi il seguente comando nella finestra della console del tuo debugger di Chrome: window.location.pathname.split("/").slice(-1).join().split(".").shift()

Se devi elaborare solo il nome del file e la sua estensione (es .:) theNameWithExt = "filename.jpg":

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

il risultato sarà theName == "nomefile" , lo stesso di cui sopra;

Appunti:

  1. Il primo è un po 'più lento perché esegue più operazioni; ma funziona in entrambi i casi, in altre parole può estrarre il nome del file senza estensione da una determinata stringa che contiene un percorso o un nome file con es. Mentre il secondo funziona solo se la variabile data contiene un nome file con ext come nomefile.ext ma è un po 'più veloce.
  2. Entrambe le soluzioni funzionano per file sia locali che server;

Ma non posso dire nulla sul confronto delle prestazioni con altre risposte né sulla compatibilità del browser o del sistema operativo.

snippet di lavoro 1: il percorso completo

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

snippet di lavoro 2: il nome del file con estensione

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

snippet di lavoro 2: il nome del file con doppia estensione

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


3

Anche se è piuttosto tardi, aggiungerò un altro approccio per ottenere il nome del file senza estensione usando semplicemente il vecchio JS-

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


o path.split('.').pop()per le estensioni di una parte di file
mixdev

Stava davvero cercando di ottenere il nome del file, non l'estensione!
Munim Dibosh,

3

Node.js rimuove l'estensione dalla directory di mantenimento del percorso completo

https://stackoverflow.com/a/31615711/895245 per esempio ha fatto path/hello.html-> hello, ma se vuoi path/hello.html-> path/hello, puoi usare questo:

#!/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));

directory degli output:

path/hello

Anche https://stackoverflow.com/a/36099196/895245 raggiunge questo obiettivo, ma trovo questo approccio un po 'più semanticamente piacevole.

Testato in Node.js v10.15.2.


0

È qui che le espressioni regolari sono utili! Il .replace()metodo Javascript avrà un'espressione regolare e puoi utilizzarlo per ottenere ciò che desideri:

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

0

Un altro esempio: supponiamo che il nostro file sia un'immagine jpg >> es: var yourStr = 'test.jpg';

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

0

Puoi usare pathper manovrare.

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

Produzione

> filePath
'/User/HELLO/WORLD/FILENAME'
> fileName
'FILENAME'
> MYPATH
'/User/HELLO/WORLD/FILENAME.js'


0

Questo è il codice che uso per rimuovere l'estensione da un nome file, senza usare regex o indexOf (indexOf non è supportato in IE8). Presuppone che l'estensione sia qualsiasi testo dopo l'ultimo '.' carattere.

Funziona per:

  • file senza estensione: "myletter"
  • file con '.' nel nome: "my.letter.txt"
  • lunghezza sconosciuta dell'estensione del file: "my.letter.html"

Ecco il codice:

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

fallisce hello.tar.gz, l'output è hellotar.
Asif Ali,

#AsifAli grazie hai ragione, ho dimenticato di leggere l'estensione del file. Ho aggiornato la risposta, spero che funzioni ora.
Piccolo cervello,

-3

Vorrei usare qualcosa come x.substring (0, x.lastIndexOf ('.')). Se stai andando per le prestazioni, non andare per javascript :-p No, un'altra affermazione in realtà non ha importanza per il 99,99999% di tutti gli scopi.


2
"Se hai intenzione di esibirti, non scegliere affatto javascript" - Cos'altro stai suggerendo di usare nelle applicazioni web ...?
TJ,

Non menziona le applicazioni web.
Lucas Moeskops,

1
Questa domanda è stata posta e la risposta è stata pubblicata nel 2010, 7 anni fa, e JavaScript era praticamente utilizzato solo nelle applicazioni web. (Il nodo era appena nato, non aveva nemmeno una guida o NPM in quel momento)
TJ

;-) Tuttavia, se le prestazioni sono importanti per attività come questa, potresti considerare di farlo sul back-end ed elaborare i risultati sul front-end.
Lucas Moeskops,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.