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

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». Внутри классов символов символ "." не является специальным символом («метасимволом»).

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

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

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

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

Neel
источник
3
String str="1.2.3";
String[] cats = str.split(Pattern.quote("."));
Магнус Перссон
источник
2

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

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

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

Мартин Смит
источник
2

Обычно НЕ стоит разоблачать его вручную. Для этой задачи в классе Pattern есть метод:

java.util.regex
static String quote(String s) 
Кристиан Улленбум
источник
1

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

Боб Финчаймер
источник
0

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

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

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

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

Решение, которое сработало для меня, следующее

filename.split ("[.]");

Хорхе Сантос
источник
0

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

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

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

Никита
источник
-2

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

Виджей Мэтью
источник