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

Java String split removed empty values

Java String split удалил пустые значения

Я пытаюсь разделить значение с помощью разделителя. Но я нахожу удивительные результаты

String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);

Я ожидаю получить 8 значений. [5,6,7, ПУСТО, 8, 9, ПУСТО, EMPTY]
Но я получаю только 6 значений.

Есть идеи и как исправить. Независимо от того, где находится пустое значение, оно должно быть в массиве.

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

split(delimiter) по умолчанию удаляет конечные пустые строки из результирующего массива. Чтобы отключить этот механизм, нам нужно использовать перегруженную версию split(delimiter, limit) с limit значением, равным отрицательному, например

String[] split = data.split("\\|", -1);

Немного подробнее:

split(regex) внутренне возвращает результат split(regex, 0) и в документации этого метода вы можете найти (выделено мной)


Параметр limit определяет количество раз, когда применяется шаблон, и, следовательно, влияет на длину результирующего массива.


Если ограничение n больше нуля, то шаблон будет применен не более n - 1 раза, длина массива не будет больше n, а последняя запись массива будет содержать все входные данные за последним согласованным разделителем.


Если n является неположительным, то шаблон будет применен столько раз, сколько возможно, и массив может иметь любую длину.


Если n равно нулю, то шаблон будет применен столько раз, сколько возможно, массив может иметь любую длину, а завершающие пустые строки будут отброшены.


Исключение:

Стоит упомянуть, что удаление завершающей пустой строки имеет смысл только в том случае, если такие пустые строки были созданы механизмом разделения. Итак, "".split(anything) поскольку мы не можем разбивать "" дальше, мы получим в результате [""] массив.
Это происходит потому, что разделения здесь не произошло, поэтому, "" несмотря на то, что оно пустое и завершающее, представляет собой исходную строку, а не пустую строку, которая была создана в процессе разделения.

Ответ 2

Из документации String.split(String regex):


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


Таким образом, вам придется использовать версию с двумя аргументами String.split(String regex, int limit) с отрицательным значением:

String[] split = data.split("\\|",-1);

Doc:


Если ограничение n больше нуля, то шаблон будет применен не более n - 1 раза, длина массива не будет больше n, а последняя запись массива будет содержать все входные данные за последним соответствующим разделителем. Если n не является положительным, то шаблон будет применен столько раз, сколько возможно, и массив может иметь любую длину. Если n равно нулю, то шаблон будет применен столько раз, сколько возможно, массив может иметь любую длину, а конечные пустые строки будут отброшены.


При этом не будут удалены никакие пустые элементы, включая завершающие.

Ответ 3

String[] split = data.split("\\|",-1);

Это не является фактическим требованием за все время. Недостаток вышеизложенного показан ниже:

Scenerio 1:
When all data are present:
String data = "5|6|7||8|9|10|";
String[] split = data.split("\\|");
String[] splt = data.split("\\|",-1);
System.out.println(split.length); //output: 7
System.out.println(splt.length); //output: 8

Когда отсутствуют данные:

Scenerio 2: Data Missing
String data = "5|6|7||8|||";
String[] split = data.split("\\|");
String[] splt = data.split("\\|",-1);
System.out.println(split.length); //output: 5
System.out.println(splt.length); //output: 8

Реальное требование - длина должна быть 7, хотя данные отсутствуют. Потому что бывают случаи, например, когда мне нужно вставить в базу данных или что-то еще. Мы можем достичь этого, используя приведенный ниже подход.

    String data = "5|6|7||8|||";
String[] split = data.split("\\|");
String[] splt = data.replaceAll("\\|$","").split("\\|",-1);
System.out.println(split.length); //output: 5
System.out.println(splt.length); //output:7

Что я здесь сделал, так это то, что я удаляю канал "|" в конце, а затем разделяю строку. Если у вас есть "," в качестве разделителя, то вам нужно добавить ",$" внутри replaceAll.

Ответ 4

Из документа по API String.split():


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


Перегруженная строка.split(regex, int) больше подходит для вашего случая.

java string