Разбор строк в Java с вкладкой разделителя "\ t" с использованием split

java string tab-delimited

206566 просмотра

6 ответа

Я обрабатываю строку, разделенную табуляцией. Я выполняю это с помощью splitфункции, и она работает в большинстве ситуаций. Проблема возникает, когда поле отсутствует, поэтому вместо получения значения NULL в этом поле я получаю следующее значение. Я храню проанализированные значения в массиве строк.

String[] columnDetail = new String[11];
columnDetail = column.split("\t");

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

Автор: lakhaman Источник Размещён: 12.11.2019 09:34

Ответы (6)


85 плюса

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

Сплит-метод даст вам список. проблема в том, что вы пытаетесь заранее определить, сколько вхождений у вас есть на вкладке, но как вы на самом деле знаете это? Попробуйте использовать Scanner или StringTokenizer и просто узнайте, как работает разбиение строк.

Позвольте мне объяснить, почему \ t не работает и почему вам нужно \\\\сбежать \\.

Итак, когда вы используете Split, он на самом деле принимает регулярное выражение (Regular Expression), и в регулярном выражении вы хотите определить, на какой символ делить, и если вы пишете \ t, это на самом деле не означает, \tи что вы хотите разделить на это \tверно? Итак, просто написав, \tвы говорите своему процессору регулярных выражений, что «Эй, разделить по символу, который экранирован, t» НЕ «Эй, разделить по всем персонажам, похожим на \t». Заметили разницу? Использование \ означает что-то избежать. И \в регулярных выражениях означает нечто совершенно иное, чем вы думаете.

Вот почему вам нужно использовать это решение :

\\t

Чтобы сказать процессору регулярных выражений искать \ t. Хорошо, так зачем вам два из них? Ну, первый \ избегает второго, что означает, что он будет выглядеть так: \ t, когда вы обрабатываете текст!

Теперь скажем, что вы хотите разделить \

Что ж, тогда вы останетесь с \\, но видите, это не работает! потому что \ попытаюсь убежать от предыдущего символа! Вот почему вы хотите, чтобы вывод был \\, и поэтому вам нужно иметь \\\\.

Я очень надеюсь, что приведенные выше примеры помогут вам понять, почему ваше решение не работает и как победить другие!

Я уже давал вам этот ответ раньше, может быть, вам стоит начать смотреть на них сейчас.

ДРУГИЕ МЕТОДЫ

StringTokenizer

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

пример

 StringTokenizer st = new StringTokenizer("this is a test");
 while (st.hasMoreTokens()) {
     System.out.println(st.nextToken());
 }

Это будет выводить

 this
 is
 a
 test

Вы используете Второй конструктор для StringTokenizer, чтобы установить разделитель:

StringTokenizer(String str, String delim)

сканер

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

пример

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");

 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());

 s.close(); 

Выход будет

 1
 2
 red
 blue 

Это означает, что оно будет вырезать слово «рыба» и даст вам остальное, используя «рыбу» в качестве разделителя.

примеры взяты из Java API

Автор: Filip Ekberg Размещён: 28.10.2009 08:09

20 плюса

Попробуй это:

String[] columnDetail = column.split("\t", -1);

Прочитайте Javadoc на String.split (java.lang.String, int) для объяснения о параметре limit функции split:

split

public String[] split(String regex, int limit)
Splits this string around matches of the given regular expression.
The array returned by this method contains each substring of this string that is terminated by another substring that matches the given expression or is terminated by the end of the string. The substrings in the array are in the order in which they occur in this string. If the expression does not match any part of the input then the resulting array has just one element, namely this string.

The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.

The string "boo:and:foo", for example, yields the following results with these parameters:

Regex   Limit   Result
:   2   { "boo", "and:foo" }
:   5   { "boo", "and", "foo" }
:   -2  { "boo", "and", "foo" }
o   5   { "b", "", ":and:f", "", "" }
o   -2  { "b", "", ":and:f", "", "" }
o   0   { "b", "", ":and:f" }

Когда пропадут последние несколько полей (я гость, это ваша ситуация), вы получите такой столбец:

field1\tfield2\tfield3\t\t

Если ограничение не установлено для split (), ограничение равно 0, что приведет к тому, что «завершающие пустые строки будут отброшены». Таким образом, вы можете получить только 3 поля: {"field1", "field2", "field3"}.

Когда limit установлен в -1, неположительное значение, завершающие пустые строки не будут отброшены. Таким образом, вы можете получить 5 полей с последними двумя пустыми строками, {"field1", "field2", "field3", "", ""}}.

Автор: Happy3 Размещён: 31.10.2012 01:03

6 плюса

Ну, никто не ответил - что отчасти является ошибкой вопроса: входная строка содержит одиннадцать полей (это можно вывести), но сколько вкладок? Скорее всего, ровно 10. Тогда ответ

String s = "\t2\t\t4\t5\t6\t\t8\t\t10\t";
String[] fields = s.split("\t", -1);  // in your case s.split("\t", 11) might also do
for (int i = 0; i < fields.length; ++i) {
    if ("".equals(fields[i])) fields[i] = null;
}
System.out.println(Arrays.asList(fields));
// [null, 2, null, 4, 5, 6, null, 8, null, 10, null]
// with s.split("\t") : [null, 2, null, 4, 5, 6, null, 8, null, 10]

Конечно, если поля содержат вкладки, это не будет работать должным образом.
В -1означает: применить шаблон столько раз , сколько необходимо - так трейлинг полей (11 - й) будут сохранены (как пустые строки ( "") , если отсутствует, что должны быть включены в nullявном виде).

Если, с другой стороны, нет никаких вкладок для пропущенных полей - "5\t6"как и допустимая входная строка, содержащая только поля 5,6 - нет способа получить fields[]сквозное разделение.

Автор: Mr_and_Mrs_D Размещён: 06.12.2012 10:21

5 плюса

String.split Реализации будут иметь серьезные ограничения, если данные в самом поле с разделителями табуляции содержат символы новой строки, табуляции и, возможно, символы ".

Форматы, разделенные табуляцией, существуют уже много лет, но формат не стандартизирован и варьируется. Многие реализации не экранируют символы (переводы строк и табуляции), появляющиеся в поле. Скорее, они следуют соглашениям CSV и заключают любые нетривиальные поля в «двойные кавычки». Тогда они избегают только двойных кавычек. Таким образом, «линия» может распространяться на несколько строк.

Читая вокруг, я услышал, что «просто используйте инструменты Apache», что звучит как хороший совет.

В итоге я лично выбрал opencsv . Я нашел его легким, и поскольку он предоставляет опции для экранирования и кавычек, он должен охватывать большинство популярных форматов данных, разделенных запятыми и табуляцией.

Пример:

CSVReader tabFormatReader = new CSVReader(new FileReader("yourfile.tsv"), '\t');
Автор: Luke Usherwood Размещён: 03.11.2011 02:57

1 плюс

У меня был тот же вопрос, и я заметил ответ в каком-то уроке. В общем случае вам нужно использовать вторую форму метода split, используя

split(regex, limit)

Вот полный учебник http://www.rgagnon.com/javadetails/java-0438.html

Если вы установите какое-либо отрицательное число для параметра limit, вы получите пустые строки в массиве, где фактические значения отсутствуют. Чтобы использовать это, ваша исходная строка должна иметь две копии разделителя, т.е. у вас должно быть \ t \ t там, где значения отсутствуют.

Надеюсь это поможет :)

Автор: Ivan Marinov Размещён: 11.07.2014 07:10

0 плюса

Вы можете использовать yourstring.split ("\ x09"); Я проверил это, и это работает.

Автор: RickeyShao Размещён: 23.01.2019 08:34
Вопросы из категории :
32x32