【问题标题】:Using Java to read and process textfile with custom column and row separators使用 Java 读取和处理带有自定义列和行分隔符的文本文件
【发布时间】:2011-11-30 20:06:32
【问题描述】:

我有一个文本文件,其中包含从网页上抓取的内容。文本文件的结构如下:

|NEWTAB|lkfalskdjlskjdflsj|NEWTAB|lkjsldkjslkdjf|NEWTAB|sdlfkjsldkjf|NEWLINE|lksjlkjsdl|NEWTAB|lkjlkjlkj|NEWTAB|sdkjlkjsld

|NEWLINE|表示新行的开始(即数据中的新行) |新标签|表示一行中新字段的开始(即数据中的新列)

我需要将文本文件拆分为字段和行并存储在数组或其他一些数据结构中。 |NEWLINE| 之间的内容字符串可能包含实际的新行(即 \n),但这些并不表示数据中的实际新行。

我首先逐个阅读每个字符,然后查看 8 个连续字符的集合,看看它们是否包含 |NEWTAB|。我的方法被证明是不可靠和丑陋的。我正在寻找这方面的最佳实践。最好的方法是将整个文本文件作为单个字符串读取,然后在“|NEWLINE|”上使用字符串拆分然后使用“|NEWTAB|”对结果字符串进行字符串拆分?

非常感谢!

【问题讨论】:

  • 使用 OpenCSV,您可以设置自定义分隔符:opencsv.sourceforge.net/#custom-sepators
  • 你试过 java.util.Scanner 了吗?
  • String.split() 有什么问题?或者像@Jomoos 提到的扫描仪?
  • 也许我太仓促了,无法忽略字符串拆分。我现在试试看。

标签: java string text text-files


【解决方案1】:

我认为其他答案也可以,但我的解决方案如下:

FileReader inputStream = null;
StringBuilder builder = new StringBuilder();

try {
    inputStream = new FileReader(args[0]);
    int c;
    char d;

    while ((c = inputStream.read()) != -1) {
        d = (char)c;
        builder.append(d);
    }
} 

finally {
    if (inputStream != null) {
        inputStream.close();
    }
}   

String myString = builder.toString();

String rows[] = myString.split("\\|NEWLINE\\|");

for (String row : rows) {
    String cols[] = row.split("\\|NEWTAB\\|");

    /* do something with cols - e.g., store */
}

【讨论】:

    【解决方案2】:

    你可以这样做:

    Scanner scanner = new Scanner(new File("myFile.txt"));
    
    List<List<String>> rows = new ArrayList<List<String>>();
    List<String> column = new ArrayList<String>();
    
    while (scanner.hasNext()) {
    
        for (String elem : scanner.nextLine().split("\\|")) {
    
        System.out.println(elem);
    
        if (elem.equals("NEWTAB") || elem.equals(""))
            continue;
        else if (elem.equals("NEWLINE")) {
            rows.add(column);
            column = new ArrayList<String>();
        } else
            column.add(elem);
        }       
    }
    

    我花了一些时间来写它,因为我在这台计算机上没有 IntelliJ 或 Eclipse,必须使用 Emacs。

    编辑:这比我喜欢的要冗长一些,但它适用于作为文本一部分的|s:

    Scanner scanner = new Scanner(new File("myFile.txt"));
    List<List<String>> rows = new ArrayList<List<String>>();
    List<String> lines = new ArrayList<String>();
    String line = "";
    
    while (scanner.hasNext()) {     
        line += scanner.nextLine();
        int index = 0;      
        while ((index = line.indexOf("|NEWLINE|")) >= 0) {
            lines.add(line.substring(0, index));
            line = line.substring(index + 9);       
        }       
    }
    
    if (!line.equals(""))
        lines.add(line);
    
    for (String l : lines) {
        List<String> columns = new ArrayList<String>();
        for (String column : l.split("\\|NEWTAB\\|"))
            if (!column.equals(""))
                columns.add(column);
        rows.add(columns);
    }
    

    【讨论】:

    • 谢谢。这看起来不错,我正试图 100% 理解它。如果有“|”,这会起作用吗出现在我的文本中而不是在 |NEWTAB| 中还是 |NEWLINE|?
    • @Andrew:不,它会失败。请参阅编辑以获取适用于文本中出现的管道 (|) 的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2015-07-07
    • 2021-08-14
    • 2019-12-07
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    相关资源
    最近更新 更多