3

我正在尝试读取以这种形式编写的文本文件:

    AB523:[joe, pierre][charlie][dogs,cat]
    ZZ883:[ronald, zigomarre][pele]

我想创建我的结构并正确检索信息。

AB523 --- 一个人
joe,pierre --- 一个人
charlie --- 一个人
dogs,cat --- 一个人

我不确定应该使用什么最好的技术。我已经尝试过 StringTokenizer ...并使用了 regEx,但我无法正确使用

你有什么解决办法吗?或建议

写入文本文件时的约定是什么?分隔符的最佳实践是什么?

编辑:文本文件也是由我生成的,所以我可以控制整个模式。重新阅读时减少工作量的最佳输出模式是什么?

4

5 回答 5

2

我会在这里使用正则表达式,因为它似乎需要维护的代码更少,而且您的语言肯定是常规的。连同一个java.util.Scanner实例以提高效率。这是一些代码:

import java.io.Reader;
import java.io.StringReader;
import java.util.Scanner;
import java.util.regex.Pattern;

public class ScannerTest {

private static final Pattern header = Pattern.compile("(.*):");
private static final Pattern names = Pattern.compile("\\[([^\\]]+)\\]");

public static void main(String[] args) {

    Reader reader = new StringReader(
            "AB523:[joe, pierre][charlie][dogs,cat]\n"
                    + "ZZ883:[ronald, zigomarre][pele]");

    Scanner scanner = new Scanner(reader);
    scanner.useDelimiter("\n");

    while (scanner.hasNext()) {
        String h = scanner.findInLine(header);
        // Substring removes trailing ':'.
        System.out.println(h.substring(0, h.length() - 1));

        String n;
        while ((n = scanner.findInLine(names)) != null)
            // Substring removes '[' and ']'.
            System.out.println(n.substring(1, n.length() - 1));

        if (scanner.hasNext())
            scanner.nextLine();
    }
}
}

尽管如此,我仍然无法删除子字符串调用,也许这隐藏了一些低效率。我的猜测是,由于字符串的不变性,不应该为这种情况重新创建字符串。

编辑:为了获得更好的性能,我还会考虑手工制作的递归下降解析器

于 2011-11-01T04:50:30.747 回答
1

使用String#splitPattern#split方法。例如,

   String[] list ="AB523:[joe, pierre][charlie][dogs,cat]".split("[:\\[\\]]+");
   for(String s : list)
       System.out.println(s);
于 2011-11-01T06:00:58.473 回答
0

单字符分隔符很容易拆分:String.split() 函数将拆分字符或字符串。它们完全符合 StringTokenizer 的功能,但语法更简洁。也就是说,String[] items = myString.split(",")看起来比

StringTokenizer st = new StringTokenizer(myString, ","); 
while(st.hasMoreTokens()){
    myList.add(st.nextToken();
}

split我说的是将来使用。)

但是,看起来您的情况稍微复杂一些,您需要将左边的东西[]. 这需要正则表达式和捕获组。就像是/\[(.*)\]/

CSV(逗号分隔值)对于简单的表格数据很常见,格式甚至在一定程度上标准化。如果要表示更复杂的对象,则可以使用 JSON 或 SOAP。如果您只使用 Java 的存储,请查看 Java 的内置序列化功能。

由于您在本地使用它,并且可能正在保存某种 Java 对象来表示它,因此一种方法是Serializable在表示您的数据的任何对象中实现。

如果你不喜欢这样,我会选择 JSON,因为它看起来像你在做某种树结构。

于 2011-11-01T03:50:43.650 回答
0

由于您可以控制文件格式,我建议使用制表符分隔。许多其他程序(例如 Excel)将读取制表符分隔。所以文件如下所示(\t 代表选项卡)

AB523\tjoe, pierre\tcharlie\tdogs,cat
ZZ883\tronald, zigomarre\tpele

注意 - 您不能使用逗号分隔 (CSV),这是另一种常见格式,因为逗号是字符串中的合法值。同样,如果制表符是字符串中的合法字符,制表符分隔也会出现问题。

像其他人建议的那样, String.split() 是解析文件的好方法。

于 2011-11-01T05:51:32.090 回答
0

如果您正在生成数据文件,请在标准固件中生成它,例如 CSV(用于简单线性数据)或 Json(用于结构化数据)甚至 XML(用于结构化数据的大量处理)。

于 2011-11-01T06:59:49.410 回答