Разделение строки Java удалено пустым значением
Я пытаюсь разделить значение с помощью разделителя.
Но я нахожу удивительные результаты
String data = "5|6|7||8|9||";
String[] split = data.split("\\|");
System.out.println(split.length);
Я ожидаю получить 8 значений. [5,6,7, EMPTY, 8,9, EMPTY, УДАЛИТЬ]
Но я получаю только 6 значений.
Любая идея и как исправить. Независимо от значения EMPTY в любом месте, оно должно быть в массиве.
Ответы
Ответ 1
split(delimiter)
по умолчанию удаляет завершающие пустые строки из массива результатов. Чтобы отключить этот механизм, нам нужно использовать перегруженную версию split(delimiter, limit)
с limit
, установленную на отрицательное значение, например
String[] split = data.split("\\|", -1);
Немного больше деталей:
split(regex)
внутренне возвращает результат split(regex, 0)
и в документации этого метода вы можете найти (акцент мой)
Параметр limit
управляет количеством применений шаблона и, следовательно, влияет на длину результирующего массива.
Если предел n
больше нуля, шаблон будет применяться не более n - 1 раз, длина массива будет не больше n, а последняя запись массива будет содержать все входные данные за последним согласованным разделителем,
Если n
неположительный, тогда шаблон будет применяться столько раз, сколько возможно, и массив может иметь любую длину.
Если n
ноль, то шаблон будет применяться столько раз, сколько возможно, массив может иметь любую длину, а завершающие пустые строки будут отброшены.
Exception
Стоит упомянуть, что удаление пустой пустой строки имеет смысл только в том случае, если такая пустая строка создается из механизма разделения. Итак, для "".split(anything)
, так как мы не можем разделить ""
дальше, мы получим как результат массив [""]
.
Это происходит из-за того, что split здесь не произошло, поэтому ""
, несмотря на то, что он пуст, а trailing представляет собой исходную строку, а не пустую строку, созданную процессом разделения.
Ответ 2
Из документации String.split(String regex)
:
Этот метод работает, как если бы он вызывал метод разделения с двумя аргументами с заданным выражением и предельным аргументом нулевого. Таким образом, конечные пустые строки не включаются в результирующий массив.
Таким образом, вам придется использовать две версии аргументов String.split(String regex, int limit)
с отрицательным значением:
String[] split = data.split("\\|",-1);
Doc:
Если предел n больше нуля, шаблон будет применен не более n - 1 раз, длина массива будет не больше n, а последний элемент массива будет содержать все входные данные за пределами последнего сопоставленного разделителя. Если n не является положительным, шаблон будет применяться столько раз, сколько возможно, и массив может иметь любую длину. Если n равно нулю, шаблон будет применяться столько раз, сколько возможно, массив может иметь любую длину, а завершающие пустые строки будут отброшены.
Это не будет содержать никаких пустых элементов, включая конечные.
Ответ 3
От Домен API:
Разделяет эту строку вокруг совпадений данного регулярного выражения. Этот метод работает, как если бы, используя метод разделения с двумя аргументами с помощью данное выражение и предельный аргумент нуля. Трейлинг пустой поэтому строки не включены в результирующий массив.
Перегружен String.split(regex, int) более подходит для вашего случая.
Ответ 4
Другой вариант - использовать разветкитель Guava. У него нет накладных расходов на регулярное выражение (которое вам не нужно в этом случае) и по умолчанию не отбрасывает пустые строки.
Например:
String data = "5|6|7||8|9||";
Iterable<String> results = Splitter.on('|').split(data);
// convert to array
String[] asArray = Iterables.toArray(results, String.class);
Для получения дополнительной информации см. wiki:
https://github.com/google/guava/wiki/StringsExplained
Ответ 5
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.
Ответ 6
у вас может быть несколько разделителей, включая пробельные символы, запятые, точки с запятой и т.д., используйте разделители в повторяемой группе с помощью [] +, например
String[] tokens = "a , b, ,c; ;d, ".split( "[,; \t\n\r]+" );
у вас будет 4 жетона - a, b, c, d
ведущие разделители в исходной строке должны быть удалены перед применением этого разделения.
в качестве ответа на заданный вопрос:
String data = "5|6|7||8|9||";
String[] split = data.split("[\\| \t\n\r]+");
пробелы добавляются на всякий случай, если вы будете использовать их как разделители вместе с |