【问题标题】:parse text file delimited by | operator and retain the header column name解析由 | 分隔的文本文件运算符并保​​留标题列名称
【发布时间】:2026-02-05 00:25:02
【问题描述】:

我有一个文本文件,其中的字段由 | 分隔操作员。 txt 文件中的第一行包含列名称。我能够根据 | 解析和拆分字段操作员使用扫描仪,但我需要每个字段值的标题列名称

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

金刚||金||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();
    }

我需要的结果如下:

名字 -> 孔

姓氏 -> 国王

年龄 -> 20

薪水 -> 1000 美元


名字 -> 史蒂夫

姓氏 -> 罗杰斯

年龄 ->

薪水 -> $2000

任何帮助表示赞赏..

【问题讨论】:

  • 只要使用任何标准的 CSV 库,就可以停止重新发明*。任何解析器都可以在几行代码中正确地做到这一点。我建议您为您的对象创建一个 bean 类型 - 然后读入一个 bean 列表。 For example.

标签: java spring parsing java.util.scanner bufferedreader


【解决方案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

【讨论】:

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