Java - как разбить строку, основанную на столбцах?

У меня есть следующие 2 строки в файле:

16.1 14.3 8.8 7.0 7.85 13.29 18.75 13.08 13.10

6.7 5.4 6.39

Я могу разделить 1-ю строку с помощью регулярного выражения "\\ s +". Но я не могу разбить вторую строку. Я хочу разделить приведенные выше строки таким образом, чтобы получить следующий результат:

row[1] = [16.1, 14.3, 8.8, 7.0, 7.85, 13.29, 18.75, 13.08, 13.10]
row[2] = [6.7, 5.4, null, null, 6.39, null, null, null, null]

Ниже приведен снимок экрана с тем, что мне нужно проанализировать:

Java - как разбить строку, основанную на столбцах?

Не уверен, что редактирование было хорошей идеей, потому что оно определенно изменило форматирование ввода. Теперь в нем определенное количество пробелов, как раньше. Не могли бы вы на оригинальном плакате подтвердить, соответствует ли количество пробелов между вашими записями какому-либо определению?

Ben 15.03.2018 13:30

Может быть, чтобы уточнить, как будет выглядеть файл, если мы заменим 18.75 в первой строке на 23132.3312? Это вообще возможно? Проще говоря: когда нет определения, как будет выглядеть ваш файл, нет способа его проанализировать.

Ben 15.03.2018 13:33
"\\\s+" не является допустимым регулярным выражением. Должен быть "\\s+"
Saif Ahmad 15.03.2018 13:33

Кажется, это работает: regex101.com/r/OFWVUP/1

jrtapsell 15.03.2018 13:34

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

vasek 15.03.2018 13:35

@Ben, это редактирование было не очень хорошей идеей, потому что в моем исходном ответе нет определенного количества пробелов. Я его перередактирую.

Pranit More 15.03.2018 13:35

Хорошо. Может еще добавить, какие есть определения. Количество столбцов фиксировано? Расстояние? Размер цифр? Кодировка? Подобные вещи были бы полезны, чтобы найти способ разобрать это.

Ben 15.03.2018 13:37

Этот снимок экрана не содержит «пустых» значений. В любом случае, похоже, мы можем предположить, что столбцы содержат некоторое фиксированное количество символов (включая пробелы). Но одинаковое ли количество символов для каждого столбца?

Pshemo 15.03.2018 13:40

@Pshemo, я заменил на правильный образ.

Pranit More 15.03.2018 13:41

данные TAB разнесены?

Saif Ahmad 15.03.2018 13:58

@saifahmad, никаких данных не TAB разнесено. Найдите решение @YCF_L. Это правильное решение.

Pranit More 15.03.2018 14:02

Но его решение зависит от фиксированных 7 пробелов.

Saif Ahmad 15.03.2018 14:05

@saifahmad, Сначала я не заметил, что все столбцы имеют определенную длину символов, т.е. 7. Поэтому решение YCF_L правильное.

Pranit More 15.03.2018 15:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
13
1 366
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Мне это кажется файлом фиксированной ширины.

Пожалуйста, попробуйте следующее регулярное выражение

.{7}

Вы можете изменить значение в фигурных скобках в зависимости от ширины столбца,

.{column_width_goes_here}

Образец https://regex101.com/r/SZZxbB/1

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

List<List<String>> matrix = Arrays.asList(text.split("\n"))
            .stream()
            .map(line -> Arrays.asList(line.split("\\s+")))
            .collect(Collectors.toList())

Это дает вам 2D-массив / список значений.

При тестировании с:

String text = "16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10\n" + " 6.7    5.4                   6.39";

Это выводит:

[[16.1, 14.3, 8.8, 7.0, 7.85, 13.29, 18.75, 13.08, 13.10], [, 6.7, 5.4, 6.39]]

Это решение не соответствует моим критериям, так как мне также нужны пустые столбцы в решении.

Pranit More 15.03.2018 14:00
Ответ принят как подходящий

Кажется, что ваши входы имеют фиксированную длину (7) от начала первого числа до следующего начального числа:

16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10
^^^^^^^--------(7)

В этом случае вы можете разделить свой ввод, используя это регулярное выражение (?<=\\G.{7})Взгляни на это:

String text1 = "16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10";
String text2 = "6.7    5.4                   6.39                             ";

String[] split1 = text1.split("(?<=\\G.{7})");
String[] split2 = text2.split("(?<=\\G.{7})");

Выходы

[16.1   , 14.3   ,  8.8   ,  7.0   ,  7.85  , 13.29  , 18.75  , 13.08  ,  13.10]
[6.7    , 5.4    ,        ,        ,  6.39  ,        ,        ,        ,       ]

Лучшее решение

Если вы хотите получить null вместо пустого, вы можете использовать:

List<String> result = Arrays.asList(text2.split("(?<=\\G.{7})"))
        .stream()
        .map(input -> input.matches("\\s*") ? null : input.trim())
        .collect(toList());

Выходы

[16.1, 14.3, 8.8, 7.0, 7.85, 13.29, 18.75, 13.08, 13.10]
[6.7, 5.4, null, null, 6.39, null, null, null, null]

Вы уверены, что text2 от OP имеет эти конечные пробелы?

revo 15.03.2018 13:46

@revo, да, в нем есть конечные пробелы.

Pranit More 15.03.2018 13:49

@PranitMore вы должны упомянуть, что в вашем вопросе, пожалуйста, комментарий revo - это хороший момент

YCF_L 15.03.2018 13:51

Спасибо, YCF_L! Это решение работает. Большое спасибо! Извините, это была моя ошибка. Я должен был упомянуть о конечных пробелах раньше. И не могли бы вы объяснить это регулярное выражение (?<=\\G.{7})?

Pranit More 15.03.2018 13:58

@PranitБолее того, это трюк для разделения строки на определенную длину, чтобы понять больше, взгляните на этот ответ здесь stackoverflow.com/a/3761521/5558072

YCF_L 15.03.2018 14:04

Используйте Splitter.fixedLength(int) Гуавы

String[] rows = {
    "16.1   14.3    8.8    7.0    7.85  13.29  18.75  13.08   13.10",
    "6.7    5.4                   6.39                             "
  };
Splitter splitter = Splitter.fixedLength(7);
for(String row: rows) {
  List<String> data = splitter.splitToList(row);
  for (int i = 0; i < data.size(); i++) {
    System.out.printf("Column %d: %s%n", i+1, data.get(i));
  }
}

Другие вопросы по теме