Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

Метод 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

Ответ 2

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

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 length will be no greater than n, and the array 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"}.

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

Ответ 3

Ну никто не ответил - отчасти это ошибка вопроса: входная строка содержит одиннадцать полей (это многое можно сделать вывод), но сколько вкладок? Скорее всего точно 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[] через split.

Ответ 4

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

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

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

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

Пример:

CSVReader tabFormatReader = new CSVReader(new FileReader("yourfile.tsv"), '\t');

Ответ 5

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

split(regex, limit)

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

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

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

Ответ 6

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