Вопрос-ответ

Split string with dot as delimiter

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

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

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

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

Переведено автоматически
Ответ 1

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

String[] fn = filename.split("\\."); 
return fn[0];
Ответ 2

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

Проблема

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


  1. принимает в качестве аргумента регулярное выражение (regex), которое описывает разделитель, на который мы хотим разделить,

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

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

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


  1. создать массив типа ["" "" "" ""],

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

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

Решение

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

Таким образом, решение вашей проблемы может выглядеть следующим образом

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

Бонус

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


  • использование символьного класса split("[.]")

  • заключаем ее в кавычки split("\\Q.\\E")

  • использование правильного экземпляра шаблона с Pattern.LITERAL флагом

  • или просто используйте split(Pattern.quote(".")) и позвольте регулярному выражению выполнять экранирование за вас.

Ответ 3

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

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

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

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

int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);
Ответ 4

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

filename.split("\\.");

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

filename.split("[.]");

Классы символов представляют собой наборы символов. Вы могли бы написать

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

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

java regex string