Разделить строку с точкой в ​​качестве разделителя - PullRequest
89 голосов
/ 02 августа 2010

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

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

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

Ответы [ 11 ]

157 голосов
/ 02 августа 2010

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

String[] fn = filename.split("\\."); 
return fn[0];
16 голосов
/ 02 августа 2010

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

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

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

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

int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);
14 голосов
/ 02 августа 2010

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

filename.split("\\.");

или указание метода split на класс символов:

filename.split("[.]");

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

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

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

13 голосов
/ 05 января 2016

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

Проблема

Вам нужно знать кое-что о text.split(delim). split метод:

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

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

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

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

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

Решение

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

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

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

Бонус

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

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

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

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

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

3 голосов
/ 04 ноября 2018
String str="1.2.3";
String[] cats = str.split(Pattern.quote("."));
2 голосов
/ 02 августа 2010

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

java.util.regex
static String quote(String s) 
2 голосов
/ 02 августа 2010

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

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

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

1 голос
/ 02 августа 2010

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

0 голосов
/ 27 июля 2018

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

Если filename это просто строка ".", То fn все равно будет иметь длину 0, а fn [0] все равно выдаст исключение!

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...