解析文本文件分隔方式为 |运算符并保留标题列名称

parse text file delimited by | operator and retain the header column name

提问人: 提问时间:4/6/2019 更新时间:4/6/2019 访问量:356

问:

我有一个文本文件,其中的字段用 |算子。txt 文件中的第一行包含 Names 列。我能够根据 |运算符使用 Scanner,但我需要每个字段值的标题列名

请在下面找到我需要解析的示例文本文件内容: 名字||姓氏||年龄||工资

金刚||国王||20||1000美元

史蒂夫||罗杰斯||||2000美元

马克||更丰富||30||12000美元

斯宾塞||烹饪||31||700美元


我现在得到的结果:

名字

姓氏

年龄

工资

20

1000美元

史蒂夫

罗杰斯

2000美元

马克

丰富

30

12000美元

斯宾塞

31

700美元


我使用的示例代码:

    FileInputStream inputStream = new FileInputStream("c:\\sample\\sample.txt");
    Scanner scanner = new Scanner(inputStream, "UTF-8");
    scanner.useDelimiter("[\\||]");
    while(scanner.hasNext()){
        System.out.println(scanner.next().trim());

    }
    scanner.close();
    }

我需要的结果如下:

名字 -> Kong

姓氏 -> King

年龄 -> 20

薪水 -> $1000


名字 -> 史蒂夫

姓氏 -> 罗杰斯

年龄 ->

薪水 -> $2000

任何帮助都是值得赞赏的。

java spring 解析 java.util.scanner bufferedreader

评论

0赞 Boris the Spider 4/6/2019
只需使用任何标准 CSV 库,即可停止重新发明轮子。任何解析器都可以在几行代码中正确地执行此操作。我建议你为你的对象创建一个 bean 类型 - 然后读入一个 bean 列表。例如

答:

-1赞 dZ. 4/6/2019 #1

不知道这是否是最有效的解决方案,但这样管理它,希望它有所帮助!:)文件路径不同,因为我在 Linux 中。

FileInputStream inputStream = new FileInputStream("/home/dzandes/Music/test.txt");
Scanner scanner = new Scanner(inputStream, "UTF-8");
scanner.useDelimiter("[\\||]");

List<String> contents = new ArrayList<>();

while (scanner.hasNext()) {

     String s = scanner.next().trim();

     // First, we split the Strings with new line in between
     if (!s.isEmpty()) {
          if (s.contains("\n")) {
              String[] s_ = s.split("\n");
              for (String str : s_) {
                   contents.add(str);
               }
           } else {
               contents.add(s);
           }       
      } else {
           contents.add(s);
      }
 }
 scanner.close();

 // Then we keep the necessary empty Strings we need, e.g. Steve Roger's age, and skip the rest
 List<String> contents_ = new ArrayList<>();
 for (int j = 0; j < contents.size(); j++) {
      if (!contents.get(j).isEmpty()) {
           contents_.add(contents.get(j));
      } else {
           if (contents.get(j+1).isEmpty() 
                  && contents.get(j-1).isEmpty()) {
               contents_.add(contents.get(j));
            }
       }
  }

  /**
   * Just left this for-loop to see what the list contains after the above
   * 
   * Of course, you can comment it
   */
   for (String s : contents_) {
       System.out.println("s :" + s);
   }

   int i = 1;
   while (i*4 < contents_.size()) {
        System.out.println(contents_.get(0) + " - " + contents_.get(i*4));
        System.out.println(contents_.get(1) + " - " + contents_.get((i*4) + 1));
        System.out.println(contents_.get(2) + " - " + contents_.get((i*4) + 2));
        System.out.println(contents_.get(3) + " - " + contents_.get((i*4) + 3));
        i++;
    }

它打印,

FirstName - Kong
lastName - King
Age - 20
Salary - $1000
FirstName - Steve
lastName - Rogers
Age - 
Salary - $2000
FirstName - Mark
lastName - Richer
Age - 30
Salary - $12000
FirstName - Spencer
lastName - Cook
Age - 31
Salary - $700

评论

0赞 Boris the Spider 4/6/2019
"文件路径不同,因为我在 Linux 中。- Java 与平台无关;您的操作系统与路径语法无关。
0赞 dZ. 4/6/2019
刚刚提到它,以便我们的朋友在检查响应时看起来并不奇怪。我试图帮助我找到一个有效的解决方案,即使它不是最有效的解决方案(我提到的一个事实)。我们在这里互相帮助和学习,我想......如果你认为这种努力值得投反对票,那么,恭喜你,你是当天最酷的人!
0赞 Boris the Spider 4/6/2019
提示:只需使用两个扫描仪,就可以编写出比这更好的代码。我没有因为路径而投反对票,我投了反对票有两个原因 - 1) 这基本上是一个只有代码的答案,绝对没有解释你在做什么或它是如何工作的 - 正如你指出的那样,这是一个教学网站,2) 代码混乱且难以理解,由于使用单个扫描仪而有奇怪的解决方法 - 如果你要发布答案, 确保它干净且正确。
0赞 dZ. 4/7/2019
扫描仪被问的人使用,这就是我保持原样的原因。其余的只是一些带有相关注释的 fors 和 ifs,而不是任何难以理解的奇怪解决方法。即使很奇怪,他也可以自己问,我很乐意给出进一步的解释。你所做的是一个“阅读这个”的解决方案,任何人都可以这样做。无论如何,我不会再继续这样做了,我尊重你的意见,即使完全不同意你的思维方式。