【问题标题】:How to read tree structure tab delimeted txt file in Java如何在 Java 中读取树结构制表符分隔的文本文件
【发布时间】:2019-05-10 20:39:14
【问题描述】:

我正在尝试读取一个.txt 文件,该文件具有带标签的树结构和 我想把它转换成.csv

Category
  Subcategory
     Subcategory1
        Subcategory11
            Item1
            Item2     
        Subcategory12
            Item1
        Subcategory13
            Item1
                Item11

我想用结构创建一个.csv 文件

Category, Subcategory,Subcategory1, Subcategory11,Item1
Category, Subcategory,Subcategory1, Subcategory11,Item2 
Category, Subcategory,Subcategory1, Subcategory12,Item1
Category, Subcategory,Subcategory1, Subcategory13,Item1,Item11

到目前为止,我所做的是

public static void main(String[] args) throws IOException {
    Scanner keywords = new Scanner(new File("keywords.txt"));

     ArrayList<ArrayList<String>> keywordsList = new ArrayList<ArrayList<String>>();
     ArrayList<String> newline = new ArrayList<String>();
        while(keywords.hasNext()){
            String line = keywords.nextLine();
            String[] tokens = line.split("\t");
            for(int i=0; i<tokens.length; i++){

                    if(tokens[i] != null && !tokens[i].isEmpty()){
                        newline.add(tokens[i]);
                    }
            }

            keywordsList.add(newline);

        }

}

【问题讨论】:

  • 我用上面的数据创建了一个基本的 TreeNode,如果你扩展更多的树节点或向父节点添加更多的子节点,它就可以工作,如果下一行文本是有意的,那么缩进的数量不会很重要自动将其视为子节点。希望对您有所帮助。

标签: java tree export-to-csv csv


【解决方案1】:

这应该可以工作(警告:它可能会因意外输入而失败,即一行比前一行多 2 个制表符):

    Scanner keywords = new Scanner(new File("keywords.txt"));

    ArrayList<String> stack = new ArrayList<String>();
    ArrayList<String> csvLines = new ArrayList<String>();

    // stores the number of elements of the last line processed
    int lastSize = -1;

    while (keywords.hasNext()) {
        String line = keywords.nextLine();

        int tabs = 0;
        // Count tabs of current line
        while (line.length() > tabs // to avoid IndexOutOfBoundsException in charAt()
                && line.charAt(tabs) == '\t') {
            tabs++;
        }

        line = line.substring(tabs); // delete the starting tabs

        if (tabs <= lastSize) {
            // if the current line has the same number of elements than the previous line, 
            // then we can save the previous processed line as CSV 
            String csvLine = "";
            for (String element : stack) {
                if (csvLine.length() > 0) {
                    csvLine += ", ";
                }
                csvLine += element;
            }
            csvLines.add(csvLine);
        }

        // if the current line has less tabs than the previous, then cut the stack 
        for (int i = stack.size() - 1; i >= tabs; i--) {
            stack.remove(i);
        }

        // if the current line has more tabs than the previous, then add the new element to the stack
        if (tabs >= stack.size()) {
            stack.add(line);
        }

        // save the number of tabs of the current line
        lastSize = tabs;
    }
    keywords.close();

    // we have to save the last line processed
    if (lastSize >= 0) {
        // save line
        String csvLine = "";
        for (String element : stack) {
            if (csvLine.length() > 0) {
                csvLine += ", ";
            }
            csvLine += element;
        }
        csvLines.add(csvLine);
    }

    // print out CSV
    for (String string : csvLines) {
        System.out.println(string);
    }

【讨论】:

  • 确实有效....但是为什么有效?更多信息将对可能看到此帖子的其他人有所帮助。
  • @DevilsHnd 我已经使用 TreeNode 发布了我的答案和解释,你可以看看吗?
  • 添加了一些cmets,希望有助于更好地理解它的工作原理。
【解决方案2】:

我根据文件中每行单词的空格/缩进创建了一个非常基本的树节点结构,下面是代码(希望注释和变量名是不言自明的)。 P.S 我使用 Files.readAllLines 将整个内容读入一个列表。

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

public class Sample {

    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\Untitled.txt");
        List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);

        Node root = new Node(lines.get(0));
        root.parent = null; 
        Node currentNode = root;
        for(int i=1; i<lines.size(); i++) {
            int cCount = lines.get(i).length()-lines.get(i).trim().length();
            int pCount = lines.get(i-1).length()-lines.get(i-1).trim().length();
            if(cCount > pCount) { //if spaces are more than previous add child node
                Node node = new Node(lines.get(i).trim());
                node.parent = currentNode;
                currentNode.childrens.add(node);
                currentNode = node;
            }
            else if(cCount == pCount) {//if spaces are same add node on same level
                Node node = new Node(lines.get(i).trim());
                currentNode.parent.childrens.add(node);
                node.parent=currentNode.parent;
            }
            else if(cCount < pCount) {//if spaces are less then add node to parent of parent
                Node node = new Node(lines.get(i).trim());
                currentNode.parent.parent.childrens.add(node);
                node.parent= currentNode.parent.parent;
                currentNode = node;
            }
        }
        String result = root.name;
        createResultString(root, result);
    }

    private static void createResultString(Node root, String result) {
        for(int i=0; i<root.childrens.size(); i++) {
            Node node = root.childrens.get(i);
            String newResult = result+" , "+ node.name;
            if(!node.childrens.isEmpty()) { //recursive search for children node name
                createResultString(node, newResult);
            }else {
                System.out.println(newResult); //**This is your csv data**
            }
        }
    }

    //Sample TreeNode to hold structure
    static class Node{
        Node(String word){
            this.name = word;
        }
        String name;
        List<Node> childrens = new ArrayList<Sample.Node>();
        Node parent;        
    }
}

输出将是

Category , Subcategory , Subcategory1 , Subcategory11 , Item1
Category , Subcategory , Subcategory1 , Subcategory11 , Item2
Category , Subcategory , Subcategory1 , Subcategory12 , Item1
Category , Subcategory , Subcategory1 , Subcategory13 , Item1 , Item11

【讨论】:

  • 如果添加到输入中,这将适用于更根深蒂固和更多数据。
【解决方案3】:

我知道这并不能直接回答您的问题,但您正在解析文档,如果您正在解析文档,Finite State Machines 是一个很好的起点。

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2021-09-22
    • 2020-06-18
    • 2018-05-24
    • 1970-01-01
    相关资源
    最近更新 更多