Разбор строки Java по каналу [дубликат]

Работает на 2.7.7:

  def stepSum (суммы: List [Int], шаги: List [Int]): List [Int] = шаги соответствуют {case Nil = & gt;  sums.reverse.tail case x :: xs = & gt;  stepSum (sums.head + x :: sums, steps.tail)} days res10: Список [Int] = Список (31, 28, 31, 30, 31) stepSum (Список (0), дней) res11: Список [Int  ] = Список (31, 59, 90, 120, 151)  
203
задан Reddy 30 January 2013 в 12:43
поделиться

5 ответов

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

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

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

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

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

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

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

Исключение:

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

351
ответ дан Pshemo 16 August 2018 в 14:30
поделиться
  • 1
    Вау. который работал блестяще. но -1 как это все меняет? – Reddy 30 January 2013 в 12:47
  • 2
    вы можете даже попробовать с помощью data.split("\\|", 8) – Subhrajyoti Majumder 30 January 2013 в 12:48
  • 3
    Не используйте split("\\|", 8), потому что это ограничивает первые восемь токенов! Если ваша строка является переменной, вы должны использовать split("\\|", -1), чтобы она создавала неограниченное количество токенов, а t отбрасывать пустые токены в конце. – ADTC 19 September 2013 в 05:59
  • 4
    @Reddy -1 ( или любое отрицательное число на самом деле, неважно, что такое абсолютное значение ) говорит, что метод split сохраняет пустые токены в конце. По умолчанию 0, что указывает методу сброса пустых токенов в конце массива. – ADTC 19 September 2013 в 06:01
  • 5
    По-видимому, многие ожидали, что сохранение конечных пустых строк является функциональностью по умолчанию для split(regex). Они оказались здесь и выяснили, что это не так. – Attila Tanyi 11 July 2017 в 14:25

Другой вариант - использовать Splitter 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

3
ответ дан nickool 16 August 2018 в 14:30
поделиться

Из String.split () API Doc :

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

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

4
ответ дан PermGenError 16 August 2018 в 14:30
поделиться
  • 1
    Это объясняет поведение, но не отвечает на вопрос. – assylias 30 January 2013 в 12:46
  • 2
    @assylias добавил его к моему ответу сейчас :) – PermGenError 30 January 2013 в 12:47

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

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

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

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

Doc:

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

Это не оставит никаких пустых элементов , включая конечные.

31
ответ дан ppeterka 16 August 2018 в 14:30
поделиться

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.

0
ответ дан Yanish Pradhananga 16 August 2018 в 14:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: