Zastanawiam się, czy mam zamiar rozłupać sznurek .
we właściwy sposób? Mój kod to:
String[] fn = filename.split(".");
return fn[0];
Potrzebuję tylko pierwszej części ciągu, dlatego zwracam pierwszą pozycję. Pytam, ponieważ zauważyłem w API, że .
oznacza to dowolny znak, więc teraz utknąłem.
Widzę tutaj tylko rozwiązania, ale nie mam pełnego wyjaśnienia problemu, więc zdecydowałem się opublikować tę odpowiedź
Problem
Musisz wiedzieć kilka rzeczy o
text.split(delim)
.split
metoda:delim
istnieje na końcutext
jak ina,b,c,,
(gdzie separator jest,
)split
na początku utworzy tablicę,["a" "b" "c" "" ""]
ale ponieważ w większości przypadków tak naprawdę nie potrzebujemy tych końcowych pustych ciągów, usuwa je również automatycznie za nas. Więc tworzy kolejną tablicę bez tych końcowych pustych ciągów i zwraca ją .Musisz również wiedzieć, że kropka
.
jest znakiem specjalnym w wyrażeniu regularnym . Reprezentuje dowolny znak (z wyjątkiem separatorów linii, ale można to zmienić za pomocąPattern.DOTALL
flagi).Więc dla stringów, tak
"abc"
jakbyśmy podzielili się"."
split
metodą will["" "" "" ""]
,co oznacza, że w rezultacie otrzymamy pustą tablicę
[]
(bez elementów, nawet bez pustego łańcucha), więc nie możemy jej użyćfn[0]
ponieważ nie ma indeksu 0.Rozwiązanie
Aby rozwiązać ten problem, wystarczy utworzyć wyrażenie regularne, które będzie reprezentować kropkę. Aby to zrobić, musimy uciec od tego
.
. Jest na to kilka sposobów, ale najprościej jest prawdopodobnie użyć\
(co w String musi być zapisane jako,"\\"
ponieważ\
jest tam również specjalne i wymaga innego\
znaku ucieczki).Więc może wyglądać rozwiązanie twojego problemu
Premia
Możesz także użyć innych sposobów ucieczki przed tą kropką, np
split("[.]")
split("\\Q.\\E")
Pattern.LITERAL
flagąsplit(Pattern.quote("."))
i pozwól regex na ucieczkę za Ciebie.źródło
split("[.]")
metoda String # split (String) używa wyrażeń regularnych. W wyrażeniach regularnych znak „.” znak oznacza „dowolny znak”. Możesz uniknąć tego zachowania, zapisując znak „.”
lub nakazując metodzie split podział na klasę znaków:
Klasy znaków to zbiory znaków. Możesz pisać
a nazwa pliku będzie dzielona co „-”, „.”, „;”, „l”, „d” lub „7”. W klasach znaków znak „.” nie jest znakiem specjalnym („metaznakiem”).
źródło
Ponieważ DOT (.) Jest traktowany jako znak specjalny, a metoda split metody String oczekuje wyrażenia regularnego, które należy zrobić w ten sposób -
W Javie znaki specjalne muszą być poprzedzone znakiem „\”, ale ponieważ „\” jest również znakiem specjalnym w Javie, należy go ponownie zmienić za pomocą innego znaku „\”!
źródło
źródło
Czy nie byłoby bardziej wydajne w użyciu
jeśli chcesz tylko, co jest do pierwszej kropki?
źródło
Zwykle ręczne zdejmowanie maski nie jest dobrym pomysłem. W klasie Pattern istnieje metoda służąca do tego zadania:
źródło
Podział musi przyjmować wyrażenie regularne jako argument ... Po prostu zmień
"."
na"\\."
źródło
Uwaga: należy zachować ostrożność z tym fragmentem, nawet po usunięciu kropki!
Jeśli nazwa pliku to tylko ciąg „.”, To fn nadal będzie mieć długość 0, a fn [0] nadal będzie zgłaszać wyjątek!
Dzieje się tak, ponieważ jeśli wzorzec pasuje co najmniej raz, split odrzuci wszystkie końcowe puste ciągi (a więc także ten przed kropką!) Z tablicy, pozostawiając pustą tablicę do zwrócenia.
źródło
Rozwiązanie, które zadziałało dla mnie, jest następujące
źródło
Korzystanie z ApacheCommons jest najprostsze:
Zauważ, że wyodrębnia również nazwę pliku z pełnej ścieżki.
źródło
split
przyjmuje wyrażenie regularne jako argument. Więc powinieneś podać"\."
zamiast,"."
ponieważ"."
jest metaznakiem w wyrażeniu regularnym.źródło