Разделить строку точкой в ​​качестве разделителя


100

Мне интересно, .правильно ли я разбиваю строку ? Мой код:

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

Мне нужна только первая часть строки, поэтому я возвращаю первый элемент. Я спрашиваю, потому что заметил в API, что это .означает любой символ, так что теперь я застрял.

Ответы:


174

split()принимает регулярное выражение, поэтому вам нужно уйти, .чтобы не рассматривать его как метасимвол регулярного выражения. Вот пример:

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

17

Split использует регулярные выражения, где '.' это специальный символ, обозначающий что угодно. Вам нужно избежать этого, если вы действительно хотите, чтобы он совпадал с '.' персонаж:

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

(один '\' для экранирования '.' в регулярном выражении, а другой - для экранирования первого в строке Java)

Также я бы не советовал возвращать fn [0], поскольку, если у вас есть имя файла something.blabla.txt, которое является допустимым именем, вы не вернете фактическое имя файла. Вместо этого я думаю, что лучше использовать:

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

Вопрос помечен как Java, а не Javascript, на который вы ссылались.
Андрей Фирбинтяну

17

Я вижу здесь только решения, но нет полного объяснения проблемы, поэтому я решил опубликовать этот ответ

Проблема

Вам нужно знать несколько вещей text.split(delim). splitметод:

  1. принимает в качестве аргумента регулярное выражение (regex), которое описывает разделитель, по которому мы хотим разбить,
  2. if delimсуществует в конце textlike in a,b,c,,(где разделитель ,) splitсначала создаст массив like, ["a" "b" "c" "" ""]но поскольку в большинстве случаев нам действительно не нужны эти завершающие пустые строки, он также автоматически удаляет их для нас. Таким образом, он создает другой массив без этих завершающих пустых строк и возвращает его .

Вам также необходимо знать, что точка. - это специальный символ в регулярном выражении . Он представляет собой любой символ (кроме разделителей строк, но это можно изменить с помощью Pattern.DOTALLфлага).

Итак, для строки, например, "abc"если мы разделим "." splitметод, будет

  1. создать массив, например ["" "" "" ""],
  2. но поскольку этот массив содержит только пустые строки, и все они замыкаются, они будут удалены (как показано в предыдущем втором пункте)

который означает , что мы получим в результате пустого массива [](без каких - либо элементов, даже не пустая строка), поэтому мы не можем использовать , fn[0]потому что нет индекса 0.

Решение

Чтобы решить эту проблему, вам просто нужно создать регулярное выражение, которое будет представлять точку. Для этого нам нужно избежать этого .. Есть несколько способов сделать это, но самый простой, вероятно, - использовать \(который в String нужно записать как, "\\"потому что там \тоже особенный и требует, чтобы другой \был экранирован).

Итак, решение вашей проблемы может выглядеть так

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

Бонус

Вы также можете использовать другие способы избежать этой точки, например

  • используя класс персонажа split("[.]")
  • заключить это в цитату split("\\Q.\\E")
  • используя правильный экземпляр Pattern с Pattern.LITERALфлагом
  • или просто используйте split(Pattern.quote("."))и позвольте регулярному выражению сбежать за вас.

это .. Мне очень нравится: split("[.]")
Dragonborn

15

метод String # split (String) использует регулярные выражения. В регулярных выражениях знак "." символ означает «любой персонаж». Вы можете избежать этого, либо экранируя символ "."

filename.split("\\.");

или сообщая методу разделения разделить на класс символов:

filename.split("[.]");

Классы символов - это наборы персонажей. Вы могли написать

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

и имя файла будет разделено через каждые «-», «.», «;», «l», «d» или «7». Внутри классов символов символ "." не является специальным символом («метасимволом»).


@MisterSmith Возможно, вы захотите взглянуть на язык программирования здесь. Мы говорим о java, а не о javascript.
f1sh

Ты абсолютно прав. Вчера я устал, кодируя на обоих языках, не замечал типов данных Java. Я думал, что, возможно, ответы были правильными еще в 2010 году, но почему-то сегодня браузеры вели себя иначе.
Mister Smith

7

Поскольку DOT (.) Рассматривается как специальный символ, а метод разделения String ожидает регулярного выражения, которое вам нужно сделать следующим образом:

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

В java специальные символы нужно экранировать с помощью «\», но поскольку «\» также является специальным символом в Java, вам нужно снова экранировать его с помощью другого «\»!



2

Разве не было бы эффективнее использовать

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

если вы хотите только то, что до первой точки?



1

Разделение должно принимать регулярное выражение в качестве аргумента ... Просто измените его "."на"\\."


0

Примечание. С этим фрагментом следует проявлять особую осторожность даже после экранирования точки!

Если имя файла - это просто строка «.», Тогда fn все равно будет иметь длину 0, а fn [0] все равно вызовет исключение!

Это связано с тем, что если шаблон соответствует хотя бы один раз, то split отбрасывает все завершающие пустые строки (а значит, и строку перед точкой!) Из массива, оставляя пустой массив для возврата.


Самое простое решение в подобных случаях - также передать лимит-аргумент 2 вызову split: String [] fn = filename.split ("[.]", 2);
avl42


0

С ApacheCommons проще всего:

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

Обратите внимание: он также извлекает имя файла из полного пути.


-2

splitпринимает в качестве аргумента регулярное выражение. Таким образом, вы должны передать "\."вместо, "."потому что "."это метасимвол в регулярном выражении.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.