Как извлечь данные из текстового файла и записать в файл CSV в Java

У меня есть текстовый файл, содержащий ссылку, имя, адрес, сумму, dateTo, dateFrom и обязательные столбцы в следующем формате:

"120030125 J Blog  23, SOME HOUSE,                 259.44  21-OCT-2013  17-NOV-2013"
"                  SQUARE, STREET, LEICESTER,"
                   LE1 2BB

"120030318 R Mxx   37, WOOD CLOSE, BIRMINGHAM,     121.96  16-OCT-2013  17-NOV-2013  Y"                      
"                  STREET, NN18 8DF"

"120012174 JE xx   25, SOME HOUSE, QUEENS          259.44  21-OCT-2013  17-NOV-2013"
"                  SQUARE, STREET, LEICESTER,"
                   LE1 2BB

"100154992 DL x    23, SOME HOUSE, QUEENS          270.44  21-OCT-2013  17-NOV-2013  Y"             
"                  SQUARE, STREET, LEICESTER,"
                   LE1 2BC

Меня интересуют только первые строки каждой строки, и я хочу извлечь данные из столбцов ссылки, имени, суммы, dateTo и dateFrom и записать их в файл CSV. В настоящее время мне удалось написать только следующий код, извлечь первые строки и избавиться от начальных и конечных двойных кавычек. Входной файл содержит пробелы, как и выходной файл.

public class ReadTxt {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("C:/Users/me/Desktop/input.txt"));
        String pattern = "\"\\d\\d\\d\\d";

        // Create a Pattern object
        Pattern r = Pattern.compile(pattern);
        int i;
        ArrayList<String> list = new ArrayList<String>();

        boolean a = true;
        PrintWriter out = new PrintWriter(new PrintWriter("C:/Users/me/Desktop/Output.txt"), a);

        try {
            String line = br.readLine();

            while (line != null) {
                Matcher m = r.matcher(line);

                if (m.find()) {
                    String temp;
                    temp = line.substring(1, line.length() - 1);
                    list.add(temp);
                }
                else {
                // do nothing
                }

                line = br.readLine();
            }
        }
        finally {
            br.close();
        }

        for (i = 0; i < list.size(); i++) {
            out.println(list.get(i));
        }

        out.flush();
        out.close();
    }
}

Приведенный выше код создаст текстовый файл со следующим выводом:

120030125  J Blog   23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013
120030318  R Mxx    37, WOOD CLOSE, BIRMINGHAM,  121.96  16-OCT-2013  17-NOV-2013  Y                      
120012174  JE xx    25, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013
100154992  DL x     23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013  Y

Мой ожидаемый результат выглядит следующим образом, но в файл csv:

120030125  J Blog  259.44  21-OCT-2013  17-NOV-2013
120030318  R Mxx   121.96  16-OCT-2013  17-NOV-2013                        
120012174  JE xx   259.44  21-OCT-2013  17-NOV-2013
100154992  DL x    259.44  21-OCT-2013  17-NOV-2013  

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


person Luiz    schedule 24.12.2013    source источник
comment
Вы показали нам свой фактический результат, можете ли вы также показать нам ожидаемый результат?   -  person Daniel Kaplan    schedule 24.12.2013
comment
Вы хотите учебник, который поможет вам понять, как записать эти данные в файл csv?   -  person Yehia Awad    schedule 24.12.2013
comment
@tieTYT - я отредактировал свой пост, чтобы показать ожидаемый результат.   -  person Luiz    schedule 24.12.2013
comment
фиксированы ли длины каждых данных?   -  person Adarsh    schedule 24.12.2013
comment
@Adarsh ​​- кроме ссылочного номера в первом столбце и столбцах дат, длина данных не является фиксированной. Я хочу иметь возможность извлекать необходимые данные и разделять их запятой и записывать их в файл CSV. Поскольку длина данных не фиксирована, а входной файл содержит пробелы, я не знаю, как извлечь необходимые данные.   -  person Luiz    schedule 24.12.2013
comment
@Luiz Но каждая строка будет иметь каждый тип данных, начиная с одного и того же индекса? Это означает, что без двойных кавычек ваше имя всегда будет в индексе 11, а сумма в индексе 51. Это правильно?   -  person Adarsh    schedule 24.12.2013
comment
@Adarsh ​​- Да, это правильно, Адарш. Однако я не знаю, как извлечь данные из и в определенный индекс в строке. Если бы вы могли предложить решение, это было бы здорово.   -  person Luiz    schedule 24.12.2013
comment
@Luiz Я разместил код, который пробовал, в разделе ответов   -  person Adarsh    schedule 24.12.2013


Ответы (2)


Вот, проверьте это. Я просто использовал массив, но вы можете внедрить нужный код в свой. Я изменил некоторые адреса (посмотрите на 2-й и 3-й адреса в массиве), чтобы для проверки были пробелы и не было пробелов в разных местах.

public class SplitData {

    public static void main(String[] args) {
        String[] array = {"120030125  J Blog   23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013",
            "120030318  R Mxx    37,WOODCLOSE,BIRMINGHAM,  121.96  16-OCT-2013  17-NOV-2013  Y 0",
            "120012174  JE xx    25, SOME HOUSE,QUEENS       259.44  21-OCT-2013  17-NOV-2013",
            "100154992  DL x     23, SOME HOUSE, QUEENS       259.44  21-OCT-2013  17-NOV-2013  Y"  
        };

        String s1 = null;
        String s2 = null;
        String s3 = null;
        String s4 = null;
        String s5 = null;
        for (String s : array) {
            String[] split = s.split("\\s+");
            s1 = split[0];
            s2 = split[1] + " " + split[2];
            for (String string: split) {
                if (string.matches("\\d+\\.\\d{2}")) {
                    s3 = string;
                    break;
                }
            }
            String[] newArray = s.substring(s.indexOf(s3)).split("\\s+");
            s4 = newArray[1];
            s5 = newArray[2];

            System.out.printf("%s\t%s\t%s\t%s\t%s\n", s1, s2, s3, s4, s5);
        }
    }  
}

Выход

120030125   J Blog  259.44  21-OCT-2013 17-NOV-2013
120030318   R Mxx   121.96  16-OCT-2013 17-NOV-2013
120012174   JE xx   259.44  21-OCT-2013 17-NOV-2013
100154992   DL x    259.44  21-OCT-2013 17-NOV-2013
person Paul Samsotha    schedule 24.12.2013
comment
Адрес может содержать или не содержать пробелы. Не вызовет ли это проблем. - person Adarsh; 24.12.2013
comment
Формат адреса значения не имеет. Адреса быть не могло. Этот код игнорирует все в расположении адреса. Он создает подстроку из индекса числа. и использует это - person Paul Samsotha; 24.12.2013
comment
Проверьте это с разными строками в адресной части. Этот код работает, поэтому вы можете поиграть с ним. - person Paul Samsotha; 24.12.2013
comment
@peeskillet - Спасибо за код. Работает как часы. Я разделил вывод запятыми следующим образом: 120030318,R Mxx,121.96,16-OCT-2013,17-NOV-2013. Не могли бы вы указать мне направление для вывода данных в файл CSV. Спасибо еще раз. - person Luiz; 24.12.2013
comment
Где находится System.out.printf(), просто замените его своим оператором println to file - person Paul Samsotha; 24.12.2013
comment
И оставьте первый цикл for. Вы можете сделать s.slpit() line.split() - person Paul Samsotha; 24.12.2013
comment
Внешний цикл просто перебирает массив, поэтому он вам не нужен. Просто поместите код в цикл while. Используйте line.split() вместо s.split(), так как line — это то, что вы хотите изначально разделить. Так что измените все s в коде на line, это переменная, которую вы используете для строки, которую читаете. Весь код может находиться внутри цикла while - person Paul Samsotha; 24.12.2013

public static void main (String[] args) throws IOException {
  BufferedReader br = new BufferedReader (new FileReader ("D:/input.txt"));
  String pattern = "\"\\d\\d\\d\\d";

  // Create a Pattern object
  Pattern r = Pattern.compile (pattern);
  int i;
  ArrayList<String> list = new ArrayList<String> ();

  boolean a = true;
  PrintWriter out = new PrintWriter (new PrintWriter ("D:/Output.csv"), a);

  try {
      String line = br.readLine ();
      line= line.trim ();
      while (line != null) {
      Matcher m = r.matcher (line);
      if (m.find ()) {
          String temp;
          temp = line.substring (0, 19) + " "
                + line.substring (51, line.length () - 1);          
          temp = temp.replaceAll ("[ ]+", " ").replace ("\"", "");
          String[] array = temp.split ("[ ]");
          temp = array[0] +","+ array[1] +" "+ array[2]+","+ array[3]+","+ array[4]+","+ array[5];
          list.add (temp);
      } else {
          // do nothing
      }

      line = br.readLine ();
      }
  }   finally {
      br.close ();
  }

  for (i = 0; i < list.size (); i++) {
      out.println (list.get (i));
  }

  out.flush ();
  out.close ();
  }

ВЫВОД

120030125,J Blog,259.44,21-OCT-2013,17-NOV-2013
120030318,R Mxx,121.96,16-OCT-2013,17-NOV-2013
120012174,JE xx,259.44,21-OCT-2013,17-NOV-2013
100154992,DL x,270.44,21-OCT-2013,17-NOV-2013
person Adarsh    schedule 24.12.2013
comment
Как заявил Луис, За исключением номера ссылки в первом столбце и столбцах дат, длина данных не является фиксированной. Поэтому я не думаю, что использование фиксированного индекса (51, line.length () - 1); сработает. Что я сделал, так это использовал индекс строки, которая соответствует номеру (259,44) - person Paul Samsotha; 24.12.2013
comment
Я прояснил это с ним в разделе комментариев. Он говорит, что каждый элемент всегда будет начинаться с фиксированного индекса. Таким образом, адресная часть всегда будет начинаться с индекса 19, а сумма всегда будет с индексом 51. - person Adarsh; 24.12.2013
comment
Окей, я не уловил. +1 - person Paul Samsotha; 24.12.2013
comment
Вы все еще можете отформатировать вывод в соответствии с желаемым выводом OP. Также вы можете выложить Y :) - person Paul Samsotha; 24.12.2013
comment
Я собирался получить окончательный вывод CSV. Спасибо, что указали на это Y. Я не заметил, что это не требуется :) - person Adarsh; 24.12.2013
comment
Всем спасибо. Я добился желаемого результата :) - person Luiz; 24.12.2013