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.