繁体   English   中英

用Java解析此文本的一种优雅方法是什么?

[英]What's an elegant way to parse this text in java?

免责声明
这里描述的解析问题非常简单。 这个问题不仅仅要求一种实现解析的方法。 -这几乎很简单-相反,它要求一种优雅的方式。 这种优雅的方式可能是先逐行读取然后自行解析每行的方式,因为显然这不是必需的。 但是,可以使用现成的标准类使用这种优雅的方法吗?

题:
我必须在Java中解析以下形式的文本(不止这3条记录;记录可以比这些示例包含更多行):

5
Dominik 3 
Markus 3 2
Reiner 1 2
Samantha 4 
Thomas 3
4
Babette 1 4 
Diana 3 4 
Magan 2 
Thomas 2 4 

第一个数字n是紧随其后的记录中的行数。 每个记录都包含一个名称,然后是0到n个整数。

我以为使用java.util.Scanner是很自然的选择,但它带来的麻烦是,在使用hasNextInt()hasNext()确定行是否开始时,我无法区分读取的数字是否是标题下一个记录的编号,或者是前一个记录的姓氏后面的最后一个数字。 上面的例子:

...
Thomas 3
4
...

在这里,我不知道如何判断34是标题还是属于Thomas的当前行。

当然,我可以先逐行读取它们,然后将它们放入另一个Scanner ,然后再次读取它们,但是这样可以有效地将整个数据解析两次,这对我来说很难看。 有没有更好的办法?

我需要类似标志的内容,该标志可以告诉我在上一个定界符跳过操作期间是否遇到换行符。

无需读入单独的扫描器,您可以读到行尾,并使用String.split ,如下所示:

while (scanner.hasNextInt()) {
    int count = scanner.nextInt();
    for (int i = 0 ; i != count ; i++) {
        if (!scanner.hasNext()) throw new IllegalStateException("expected a name");
        String name = scanner.next();
        List<Integer> numbers = new ArrayList<Integer>();
        for (String numStr : scanner.readLine().split(" ")) {
            numbers.add(Integer.parseInt(numStr));
        }
        ... // Do something with name and numbers
    }
}

这种方法避免了通过在读取名称之后(即在读取一行的中间readLine()调用readLine()来检测一行的最后一个int与下一行的第一个整数之间的差异的需要。

使用FileReaderBufferedReader读取文件,然后开始检查:

outer loop -->while readLine is not null 
if line matches //d+ --> read value of number and put it into count
from 0 to count do what you want to do  // inner loop
File file = new File("records.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));

String line = null;
   /* Read file one line at a time */
   while((line = reader.readLine()) != null){
       int noOfRecords = Integer.parseInt(line);
       /* read the next n lines in a loop */
       while(noOfRecords != 0){
           line = reader.readLine();
           String[] tokens = line.split(" ");
           noOfRecords--;
           // do what you need to do with names and numbers
       }
   }

在这里,我们一次读取一行,因此,第一次读取一行将是一个int(称为n),从那里读取某个内部循环中的下n行。 一旦完成此内部循环,它将移至外部,下次您读一行时,肯定是另一个int或EOF。 这样,您就不必处理整数解析异常,我们将只读取所有行一次:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM