JavaScript'teki bir Dizeden dosya uzantısını nasıl kırpırım?


295

Örneğin, varsayarak x = filename.jpg, Almak istediğim filenameyerde, filenameherhangi bir dosya adı olabilir (dosya adı yalnızca [a-zA-Z0-9-_] basitleştirmek içeren varsayalım.).

Ben testere x.substring(0, x.indexOf('.jpg'))üzerindeki DZone Snippet'ler ama olmaz x.substring(0, x.length-4)daha iyi performans? Çünkü, lengthbir özelliktir ve karakter kontrolü yapmazken indexOf()bir işlevdir ve karakter kontrolü yapar.



Stackoverflow.com/questions/1991608/… ile hemen hemen aynı . Ve bunlardan birçoğunu yapmazsanız, verimlilik konusunda endişe etmek Erken Optimizasyon'dur.
Arketipik Paul

ES6 yaşında, Path modülüne de bakın - düğümleri veya uygun bir transpilasyon kullanıyorsanız
Frank

Yanıtlar:


173

Uzantının uzunluğunu biliyorsanız kullanabilirsiniz x.slice(0, -4)(burada 4 uzantının üç noktası ve noktadır).

Eğer uzunluğu bilmiyorsanız @ John Hartsock regex doğru yaklaşım olacaktır.

Normal ifadeler kullanmak istemiyorsanız, bunu deneyebilirsiniz (daha az performans):

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

Uzantısı olmayan dosyalarda başarısız olacağını unutmayın.


Bu çözümü en çok seviyorum. Temiz ve dosya uzantısının her zaman olduğunu biliyorum çünkü kullanabilirsiniz .jpg. Ruby gibi bir şey arıyordum x[0..-5]ve x.slice(0, -4)harika görünüyor! Teşekkürler! Sağlanan diğer sağlam alternatifler için herkese teşekkürler!
23.11.2018

22
bu en uygun çözüm değildir, lütfen aşağıdaki diğer çözümleri kontrol edin.
bunjeeb

8
Uzantının uzunluğundan% 100 emin değilseniz, bunu yapmayın: "picture.jpeg".slice(0, -4)-> "resim."
basic6

13
Bu tehlikeli bir çözümdür, çünkü formatın uzunluğunu gerçekten bilmiyorsunuzdur.
Coder

"Uzantının uzunluğunu biliyorsanız" Bu kabul edilebilir bir varsayım olduğundan on yıllardır. Bunu artık kullanma.
Alexander - Monica'yı

454

Neyin daha hızlı performans göstereceğinden emin değilim, ancak uzantı gibi .jpegveya.html

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

15
Muhtemelen regexp'in yani yolunu ayırıcı olarak, /\.[^/.]+$/ / da izin vermeme istiyoruz
gsnedders

Bu, herhangi bir dosya uzantısı uzunluğu (.txt veya .html veya .htaccess) için çalışır ve ayrıca dosya adının ek nokta (.) Karakterleri içermesine izin verir. Uzantının kendisi bir nokta içerdiğinden örneğin .tar.gz ile başa çıkmaz. Bir dosya adının dosya uzantısından daha fazla nokta içermesi daha yaygındır. Teşekkürler!
Steve Seeger

2
@Vik 'Doğru cevap' ile kabul edilen cevap arasında bir fark vardır. Kabul edilen bir cevap sadece soruyu soran kişi için yararlı olan cevaptır.
Steven

4
Windows platformu ile ilgili sorunlar olabileceğini düşünüyorum çünkü ters eğik çizgiler olabilir. Bu nedenle normal ifade /\.[^/\\. Cialis+$/ olmalıdır.
Alex Chuev

1
@ElgsQianChen burada sorularınızı cevaplamak için harika bir araçtır regexr.com
John Hartsock

281

Gelen node.js aşağıdaki gibi uzantısı olmadan dosyanın adı elde edilebilir.

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

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

Daha fazla açıklama Node.js dokümantasyon sayfasında.


2
@Kaasdude hakkında konuştuğunuz şey ... bu yöntem etkili bir şekilde düğümdeki uzantıyı kaldırır., Ne ifade etmek istediğinizden emin değilim, ancak bu yöntem incilerle çalışır.
Erick

1
Bu yanıt sunucu tarafı düğümü ile oldukça sınırlıdır. Bunu tepki kodunda kullanmaya çalışırsanız, içe aktarılmış gibi görünmüyor.
Charlie

1
Eğer dizinleri içeren bir yoldan bir uzantısı kaldırmak isterseniz yapabilirsiniz var parsed = path.parse(filename)izledi path.join(parsed.dir, parsed.name).
Jespertheend

Başka bir olasılık let base = path.basename( file_path, path.extname( file_path ) ).
bicarlsen

116

x.length-4yalnızca 3 karakterlik uzantıları hesaplar. Ya sahipseniz filename.jpegya da filename.pl?

DÜZENLE:

Cevap vermek için ... her zaman bir uzantınız varsa .jpg, x.length-4gayet iyi çalışır.

Ancak, uzantınızın uzunluğunu bilmiyorsanız, bazı çözümlerden herhangi biri daha iyi / daha sağlamdır.

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

VEYA

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

VEYA

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

VEYA (dosya adında yalnızca bir nokta olduğu varsayımıyla)

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

VEYA (sadece bir nokta ile)

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

12
?? Dosya adınız olabilir: ex: "summer.family.jpg" bu durumda split ('.') [0] yalnızca kısmi bir dosya adı döndürür. Bunu cevaptan kaldırabilirim, ya da bu örnek için sorunun altında açıkça ifade ederim. @basarat ...
Roko C. Buljan

Parça böler ile ilgili sık sık yaptığım bir şey:var parts = full_file.split("."); var ext = parts[parts.length-1]; var file = parts.splice(0,parts.length-1).join(".");
radicand

x.split (".") bir cevap bile sayılmamalıdır. Bir '' kullandığımı biliyorum. dosya adlandırma kurallarının neredeyse hepsinde, yani 'survey.controller.js' veya 'ailem.jpg'.
Lee Brindley

@ Lee2808: Dolayısıyla sadece bir noktanın uyarısı. Bu, uygulamaya bağlı olarak bir dizi yaklaşım olduğunu göstermek içindir. Hemen hemen tüm durumlarda diğer yöntemlerden birini kullanacağım.
Jeff B

x = x.substr(0, x.lastIndexOf('.'));- Muhtemelen demek istedin x = x.substring(0, x.lastIndexOf('.'));?
Dziad Borowy

39

Belki de son noktanın uzantı sınırlayıcısı olacağı varsayımını kullanabilirsiniz.

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

Dosyanın uzantısı yoksa, boş dize döndürür. Bu işlevi kullanan düzeltmek için

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

Uyarı, dosya adı uzantısı yoksa bu başarısız olur. Boş bir dize kaldı.
Brad

18
Nokta içermeyen daha kısa sürüm. var f = x.substr(0, x.lastIndexOf('.')) || x;Boş bir dize yanlış olduğu için çalışır, bu nedenle x döndürür.
Jonathan Rowny

22

Okumak çok zor olmayan bir astar olduğu için bunu beğendim:

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


12

Bu, sınırlayıcı dizede bulunmasa bile çalışır.

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"

Bunun gibi bir astar olarak da kullanılabilir:

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

EDIT: Bu daha verimli bir çözümdür:

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

10

Geçerli bir seçenek olup olmadığını bilmiyorum ama bunu kullanın:

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.

Bu sadece bildiğim bir operasyon değil, en azından her zaman işe yaramalı!

GÜNCELLEME: Bir oneliner istiyorsanız, işte buradasınız:

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


1
Name.join ('') değil, name.join ('.') Olmalıdır. Nokta ile ayrıldınız ancak virgülle katıldınız, bu yüzden hello.name.txtgeri döndühello, name
Evil


7

İşte regex tabanlı bir çözüm daha:

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

Bu yalnızca son segmenti kesmelidir.


7

Basit olan:

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

6

Kabul edilen cevap .jpegçoğu durumda iyi bir seçim olabilecek sadece son uzatma kısmını ( ) çıkarır.

Bir kez tüm uzantıları ( .tar.gz) şerit zorunda kaldı ve dosya adları nokta içermeyecek şekilde sınırlandı (bu yüzden 2015-01-01.backup.tarbir sorun olmaz):

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


3

Tam yolu içeren bir değişkeni işlemeniz gerekiyorsa (ör .:) thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg"ve yalnızca "dosya adı" döndürmek istiyorsanız şunları kullanabilirsiniz:

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

sonuç Name == "dosyaadı" olur ;

Bunu denemek için krom hata ayıklayıcının konsol penceresine aşağıdaki komutu yazın: window.location.pathname.split("/").slice(-1).join().split(".").shift()

Yalnızca dosya adını ve uzantısını işlemeniz gerekiyorsa (ör .:) theNameWithExt = "filename.jpg":

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

sonuç, yukarıdakiyle aynı olan Name == "dosyaadı" olur ;

Notlar:

  1. Birincisi biraz daha yavaştır çünkü daha fazla işlem yapar; ancak her iki durumda da çalışır, başka bir deyişle, yol adını içeren belirli bir dizeden uzantı olmadan dosya adını veya ex ile dosya adını ayıklayabilir. İkincisi, yalnızca belirli bir değişken, filename.ext gibi ext olan bir dosya adı içeriyorsa, ancak biraz daha hızlıysa çalışır.
  2. Her iki çözüm de yerel ve sunucu dosyaları için çalışır;

Ancak ne performansların diğer cevaplarla karşılaştırılması, ne de tarayıcı veya işletim sistemi uyumluluğu hakkında hiçbir şey söyleyemem.

çalışma snippet'i 1: tam yol

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

çalışma snippet'i 2: uzantılı dosya adı

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

çalışma snippet'i 2: çift uzantılı dosya adı

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


3

Oldukça geç olmasına rağmen, düz eski JS- kullanarak uzantı olmadan dosya adını almak için başka bir yaklaşım ekleyeceğim.

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


veya path.split('.').pop()bir parça dosya uzantısı için
mixdev

Aslında uzantı değil dosya adını almaya çalışıyordu!
Munim Dibosh

3

Node.js, uzantıyı tam yol tutma dizininden kaldır

https://stackoverflow.com/a/31615711/895245 örneğin yaptı path/hello.html-> hello, ancak isterseniz path/hello.html-> path/hello, bunu kullanabilirsiniz:

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

çıktılar dizini de:

path/hello

https://stackoverflow.com/a/36099196/895245 de bunu başarıyor, ancak bu yaklaşımı biraz daha anlamsal olarak hoş buluyorum.

Node.js v10.15.2'de test edilmiştir.


0

Bu, düzenli ifadelerin işe yaradığı yerdir! Javascript'in .replace()yöntemi düzenli bir ifade alacaktır ve bunu istediğinizi gerçekleştirmek için kullanabilirsiniz:

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

0

Başka bir astar - dosyamızın bir jpg resmi olduğunu varsayalım >> ex: var yourStr = 'test.jpg';

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

0

pathManevra yapmak için kullanabilirsiniz .

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

Çıktı

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


0

Regex veya indexOf kullanmadan uzantıyı bir dosya adından kaldırmak için kullandığım kod budur (indexOf IE8'de desteklenmez). Uzantının son '.' İfadesinden sonra herhangi bir metin olduğunu varsayar. karakter.

Şunlar için çalışır:

  • uzantısı olmayan dosyalar: "myletter"
  • '.' ile dosyalar. adında: "my.letter.txt"
  • bilinmeyen dosya uzantısı uzunluğu: "my.letter.html"

İşte kod:

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

ile başarısız hello.tar.gz, çıktı hellotar.
Asif Ali

#AsifAli teşekkürler haklısın, dosya uzantısını okumayı unuttum. Cevabı güncelledim, umarım şimdi çalışır.
Küçük Beyin

-3

X.substring (0, x.lastIndexOf ('.')) Gibi bir şey kullanırdım. Performansa gidiyorsanız, javascript için hiç gitmeyin :-p Hayır, bir ifadenin tüm amaçların% 99.99999'u için gerçekten önemli değil.


2
"Performans için gidiyoruz, hiç javascript için gitmeyin" - Web uygulamalarında başka ne kullanmanızı öneririz ..?
TJ

Web uygulamalarından bahsetmiyor.
Lucas Moeskops

1
Bu soru soruldu ve 7 yıl önce 2010 yılında gönderildi ve JavaScript hemen hemen sadece web uygulamalarında kullanıldı. (Düğüm henüz doğdu, o sırada bir rehber veya NPM bile yoktu)
TJ

;-) Yine de, performans bu gibi görevler için önemliyse, bunu arka uçta yapmayı ve sonuçları ön uçta işlemeyi düşünebilirsiniz.
Lucas Moeskops
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.