Dize sınırlayıcı olarak noktalı bölme


100

Bir dizeyi .doğru şekilde bölmeye mi gideceğimi merak ediyorum ? Benim kodum:

String[] fn = filename.split(".");
return fn[0];

Dizenin yalnızca ilk kısmına ihtiyacım var, bu yüzden ilk öğeyi iade ediyorum. Soruyorum çünkü API'de bunun .herhangi bir karakter anlamına geldiğini fark ettim , bu yüzden şimdi sıkıştım.

Yanıtlar:


175

split()bir normal ifadeyi kabul eder, bu yüzden onu bir normal ifade .meta karakteri olarak düşünmemek için kaçmanız gerekir . İşte bir örnek:

String[] fn = filename.split("\\."); 
return fn[0];

17

Bölme, normal ifadeler kullanır; burada '.' her şeyi ifade eden özel bir karakterdir. Eğer gerçekten '.' İle eşleşmesini istiyorsanız, ondan kaçmanız gerekir. karakter:

String[] fn = filename.split("\\.");

(bir '\' normal ifadede '.' ve diğeri Java dizesindeki ilkinden kaçmak için)

Ayrıca fn [0] 'ı döndürmenizi önermem, çünkü adında bir dosyanız varsa something.blabla.txt, bu geçerli bir addır, gerçek dosya adını döndürmezsiniz. Bunun yerine şunu kullanmanın daha iyi olacağını düşünüyorum:

int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);

Soru, bağlantı verdiğiniz şey olan Javascript değil, Java olarak etiketlenmiştir.
Andrei Fierbinteanu

17

Burada yalnızca çözümleri görüyorum, ancak sorunun tam açıklaması yok, bu yüzden bu yanıtı göndermeye karar verdim

Sorun

Hakkında birkaç şey bilmen gerekiyor text.split(delim). splityöntem:

  1. ayırmak istediğimiz sınırlayıcıyı tanımlayan bağımsız değişken düzenli ifade (regex) olarak kabul eder ,
  2. eğer delimsonunda mevcut textolduğu gibi a,b,c,,(ayırıcı olduğu ,) splitgibi dizi yaratacaktır ilk başta ["a" "b" "c" "" ""]ama bu yana çoğu durumda biz gerçekten de bizim için bunları otomatik olarak kaldırır bu sondaki boş dizeleri gerekmez. Böylece , bu sondaki boş dizeler olmadan başka bir dizi oluşturur ve onu döndürür .

Ayrıca bilmek gerekir nokta. olduğunu özel karakter de regex . Herhangi bir karakteri temsil eder (satır ayırıcılar hariç ancak bu Pattern.DOTALLbayrakla değiştirilebilir ).

Öyleyse dize "abc"için "." splityönteme bölünürsek

  1. gibi dizi oluştur ["" "" "" ""],
  2. ancak bu dizi yalnızca boş dizeler içerdiğinden ve hepsi sonda olduğundan, kaldırılacaklar (önceki ikinci noktada gösterildiği gibi)

Bu, sonuç olarak boş bir dizi alacağımız anlamına gelir [](hiç eleman olmadan, boş dizge bile olmadan), bu yüzden kullanamayız fn[0]çünkü 0 indisi yok.

Çözüm

Bu sorunu çözmek için noktayı temsil edecek bir normal ifade oluşturmanız yeterlidir. Bunu yapmak için bundan kaçmalıyız .. Bunu yapmanın birkaç yolu vardır, ancak en basiti muhtemelen kullanmaktır \(String'de yazılması gerekir "\\"çünkü \burada da özeldir ve başka \birinin kaçmasını gerektirir ).

Yani probleminizin çözümü şöyle görünebilir:

String[] fn = filename.split("\\.");

Bonus

Bu noktadan kaçmak için başka yollar da kullanabilirsiniz.

  • karakter sınıfını kullanma split("[.]")
  • alıntıya sarmak split("\\Q.\\E")
  • uygun Desen örneğini Pattern.LITERALbayrakla kullanma
  • veya basitçe kullanın split(Pattern.quote("."))ve normal ifadenin sizin için kaçmasına izin verin.

bu .. Gerçekten beğendim: split("[.]")
Dragonborn

15

String # split (String) yöntemi normal ifadeler kullanır. Normal ifadelerde "." karakter "herhangi bir karakter" anlamına gelir. Bu davranıştan "." Karakterinden kaçarak kurtulabilirsiniz.

filename.split("\\.");

veya bölme yöntemine bir karakter sınıfında bölünmesini söylemek:

filename.split("[.]");

Karakter sınıfları, karakter koleksiyonlarıdır. Yazabilirsin

filename.split("[-.;ld7]");

ve dosya adı her "-", ".", ";", "l", "d" veya "7" olarak bölünecektir. İç karakter sınıfları, "." özel bir karakter ("meta karakter") değildir.


@MisterSmith Burada programlama diline bir göz atmak isteyebilirsiniz. JavaScript'ten değil, java'dan bahsediyoruz.
f1sh

Kesinlikle haklısın. Dün yorgundum, her iki dilde de kod yazdığım için Java veri türlerini fark etmedim. Belki cevapların 2010'da doğru olduğunu düşündüm ama bugün tarayıcılar bir şekilde farklı bir şekilde davrandılar.
Mister Smith

7

DOT (.) Özel bir karakter olarak kabul edildiğinden ve String'in split yöntemi, şu şekilde yapmanız gereken bir normal ifade beklediğinden -

String[] fn = filename.split("\\.");
return fn[0];

Java'da özel karakterlerden bir "\" ile kaçınılması gerekir, ancak "\" aynı zamanda Java'da özel bir karakter olduğundan, başka bir "\" ile ondan tekrar kaçmanız gerekir!



2

Kullanmak daha verimli olmaz mıydı

 filename.substring(0, filename.indexOf("."))

sadece ilk noktaya kadar olanı istiyorsan?


2

Genellikle maskesini elle çıkarmak iyi bir fikir DEĞİLDİR. Bu görev için Pattern sınıfında bir yöntem vardır:

java.util.regex
static String quote(String s) 

1

Bölünmüş Basitçe değişim ... bağımsız değişken olarak regex alarak edilmelidir "."için"\\."


0

Not: Nokta kaçtıktan sonra bile bu kod parçacığına daha fazla özen gösterilmelidir!

Dosya adı yalnızca "." Dizgesiyse, fn yine de 0 uzunluğunda olur ve fn [0] yine de bir istisna atar!

Bunun nedeni, eğer desen en az bir kez eşleşirse, split dizinin sonundaki tüm boş dizeleri (dolayısıyla noktadan önceki dizileri de) atacak ve döndürülecek boş bir dizi bırakacaktır.


Eldeki gibi durumlarda en kolay çözüm, bölme çağrısına 2 limit argümanını da iletmektir: String [] fn = dosyaadı.split ("[.]", 2);
avl42


0

ApacheCommons'u kullanmak en basitidir:

File file = ...
FilenameUtils.getBaseName(file.getName());

Ayrıca, tam yoldan bir dosya adı çıkarır.


-2

splitbağımsız değişken olarak bir normal ifadeyi alır. Yani geçmelidir "\."yerine "."çünkü "."regex meta karakterdir.

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.