【问题标题】:Parse plain text file with nested structure解析具有嵌套结构的纯文本文件
【发布时间】:2015-01-18 16:00:56
【问题描述】:

我正在尝试将纯文本文件解析为 ArrayListObjects。问题是它有某种嵌套结构。数据如下所示:

S   183166621   75783-29-8          0   -1  0   0   0   0
SS  183166621   0   DE  Siloxane und Silikone, di-Me, polymers mit bor oxid (B2O3)
SS  183166621   0   EN  Siloxanes and Silicones, di-Me, polymers with boron oxide (B2O3)
S   183166624   3087-36-3       221-410-8   0   -1  0   0   0   0
SS  183166624   0   DE  Titan(4+)ethanolat
SS  183166624   0   EN  Ethanol, titanium(4+) salt

所以有一行以“S”开头,代表某种物质。每个“S”行后跟多个“SS”行,其中包含不同语言中相应物质的同义词。同义词的数量不是固定的。有的只有 2 个,有的有 3 个、4 个或更多。

我的想法是创建一个Substance Object,其中包含一个包含所有可能同义词的列表。

我创建了一个BufferedReader 并尝试逐行解析文件

String line;
while((line = br.readLine()) != null) {
    if (line.startsWith("S\t")) {

        Substance substance = new Substance();
        String[] columns = line.split("\t");

        // Parse columns and store them in substance Object

    }
}

为了阅读同义词,我想启动第二个内部循环,解析以“SS”开头的所有行。当到达另一个“S”行时,内部循环停止。

String line;
while((line = br.readLine()) != null) {
    if (line.startsWith("S\t")) {

        Substance substance = new Substance();
        String[] columns = line.split("\t");

        // Parse columns and store them in substance Object

        while((line = br.readLine()) != null) {
            if (line.startsWith("SS\t")) {
                Synonym synonym = new Synonym();

                // Parse columns and store them in synonym Object

                // Add synonym to List of Synonyms of Substance 
                substance.addSynonym(synonym);
            }
            else {
                break;
            }
        }
    }
}  

这样做的问题是,在离开内循环后,外循环执行另一个readline(),因此实际的“S”行丢失了。

有人能指出我正确的方向吗?

【问题讨论】:

    标签: java parsing


    【解决方案1】:

    您已经认识到的问题是您从阅读器那里阅读了两次。我只会阅读一次并立即拆分,检查第一个标记是 S 的主要内容还是 SS 是先前阅读的主要内容的同义词。为此,您需要将 Substance substance; 变量放在循环之外。

    String line;
    Substance actualSubstance = null;
    while((line = br.readLine()) != null) {
        String[] columns = line.split("\t");
        if (columns[0].equals("S")) {
            actualSubstance = new Substance();
            // parse main substance
        } else if (columns[0].equals("SS")) {
            if(actualSubstance != null) {
                Synonym synonym = new Synonym(); 
                // parse synonim substance and add to actual main substance
                actualSubstance.addSynonym(synonym);
            } else {
                // bad format of the input file -> handle accordingly 
            }
        } else {
            // junk
        }
    }
    

    【讨论】:

      【解决方案2】:

      解决此问题的常用方法之一是保留一个引用变量来引用您创建的最后一个 Substance 对象。您在循环外定义变量。

      然后你开始解析这些行。

      如果该行以单个S 开头,则检查substance 的先前值是否不是null。如果是这样,您将其添加到您的物质列表中。然后创建一个新的Substance 并将其分配给substance

      这样,您每次点击S 行时都会开始一个新的Substance,并在看到新的S 行时将其放入列表中。

      在同一个循环中,如果行以SS 开头,则解析同义词,并使用substance.addSynonym。您知道在这个阶段您已经创建了Substance 对象,它正在substance 中等待。如果您不确定您的文件是否始终以S 开头,建议您检查null

      最后,循环结束后,substance 中有一个 Substance 对象,由于没有新的 S 行,它还没有提交到列表中。您只需将其添加到列表中即可。

      ArrayList<Substance> list = new ArrayList<>();
      String line;
      Substance substance = null ;
      
      while((line = br.readLine()) != null) {
      
          if (line.startsWith("S\t")) {
      
              if ( substance != null ) {
                 list.add( substance );
              }
      
              substance = new Substance();
              String[] columns = line.split("\t");
      
              // Parse columns and store them in substance Object
      
          else if (line.startsWith("SS\t")) {
              Synonym synonym = new Synonym();
      
              // Parse columns and store them in synonym Object
      
              // Add synonym to List of Synonyms of Substance 
              if ( substance != null ) {
                  substance.addSynonym(synonym);
              }
          }
      }
      list.add( substance );
      

      【讨论】:

        猜你喜欢
        • 2011-01-28
        • 2016-12-27
        • 1970-01-01
        • 2019-05-28
        • 2010-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多