Java扫描器和行延续

Java扫描器和行延续,java,java.util.scanner,Java,Java.util.scanner,我想从文件中读取记录。一条记录可以跨越多行。这些线由一个“-”(减号)连接。 示例文件: Alice, 23, SampleRoad 120, SampleTown Bob, 25, SampleRoad 15A, SampleTown, - Tel: 0545848, Mail: bob@hotmail.com Chris, 27, SampleRoad, SampleTown 我使用Scanner类读取文件: private static void readFile(String

我想从文件中读取记录。一条记录可以跨越多行。这些线由一个“-”(减号)连接。 示例文件:

Alice, 23, SampleRoad 120, SampleTown
Bob, 25, SampleRoad 15A, SampleTown, -
     Tel: 0545848, Mail: bob@hotmail.com
Chris, 27, SampleRoad, SampleTown
我使用Scanner类读取文件:

private static void readFile(String fileName) {

    Pattern PATTERN_RECORD = Pattern.compile(".*", Pattern.MULTILINE);

    try {
        File file = new File(fileName);
        Scanner scanner = new Scanner(file);
        scanner.useDelimiter("(?!-)[\\r\\n]+"); //not a '-' followed by crlf

        int iRecord = 0;
        while (scanner.hasNext(PATTERN_RECORD)) {
            System.out.println(++iRecord + ": " + scanner.next());
        }
        scanner.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}
我的理解是,scanners分隔符模式定义了作为“记录”处理的内容

结果是:

1: Alice, 23, SampleRoad 120, SampleTown
2: Bob, 25, SampleRoad 15A, SampleTown, -
3:          Tel: 0545848, Mail: bob@hotmail.com
4: Chris, 27, SampleRoad, SampleTown
这就是我想要的:

1: Alice, 23, SampleRoad 120, SampleTown
2: Bob, 25, SampleRoad 15A, SampleTown, Tel: 0545848, Mail: bob@hotmail.com
3: Chris, 27, SampleRoad, SampleTown

可能扫描器类不适合这里

普通阅读器在您的情况下可能会更快

    final BufferedReader in = new BufferedReader(new FileReader("/tmp/data"));
    String prev = null;
    String current = null;
    while ((current = in.readLine()) != null) {
        if (prev == null) {
            prev = current;
            continue;
        }
        final boolean shouldJoin = prev.endsWith("-");
        if (!shouldJoin) {
            System.out.println(prev);
            prev = current;
            continue;
        }
        prev = prev.substring(0, prev.length() - 1) + current.substring(5);
    }
    if (prev != null) {
        System.out.println(prev);
    }
    in.close();

普通读者在您的情况下可能会更快

    final BufferedReader in = new BufferedReader(new FileReader("/tmp/data"));
    String prev = null;
    String current = null;
    while ((current = in.readLine()) != null) {
        if (prev == null) {
            prev = current;
            continue;
        }
        final boolean shouldJoin = prev.endsWith("-");
        if (!shouldJoin) {
            System.out.println(prev);
            prev = current;
            continue;
        }
        prev = prev.substring(0, prev.length() - 1) + current.substring(5);
    }
    if (prev != null) {
        System.out.println(prev);
    }
    in.close();

问题是您的分隔符regex。你应该使用向后看而不是向前看。尝试如下更改:

scanner.useDelimiter("(?<!-)[\\r\\n]+");

scanner.useDelimiter((?问题在于您的分隔符regex。您应该使用lookback而不是lookahead。请尝试如下更改:

scanner.useDelimiter("(?<!-)[\\r\\n]+");

scanner.useDelimiter(“(?谢谢,但现在只选择了第一条记录。您知道如何在不明确定义跳过模式的情况下跳过不匹配的记录吗?这可能是因为您使用了
pattern\u record
,您是否打算使用
DOTALL
标志而不是
MULTILINE
?如果您更改了它,它会起作用,但您甚至不需要它,您还可以使用
hasNext()
scanner.useDelimiter(“(?奇怪的是,在你之前的评论之后,我对你的代码进行了测试,完全按照这些更改,它工作正常。你得到了什么输出?嗯,不知道如何在评论中插入新行:这是输出:1:Alice,23,SampleLoad 120,SampleTown
2:Bob,25,SampleTown,SampleTown,-

3:Tel:0545848,Mail: bob@hotmail.com
4:Chris,27岁,SampleLoad,SampleTown
谢谢,但现在只选择了第一条记录。您知道如何在不明确定义跳过模式的情况下跳过不匹配的记录吗?这可能是因为您的
模式\u记录
,您是否打算使用
DOTALL
标志而不是
多行
?如果您可以更改它,它会工作,但您甚至不需要它,您也可以
hasNext()
scanner.useDelimiter(“(?奇怪的是,在你之前的评论之后,我对你的代码进行了测试,完全按照这些更改,它工作正常。你得到了什么输出?嗯,不知道如何在评论中插入新行:这是输出:1:Alice,23,SampleLoad 120,SampleTown
2:Bob,25,SampleTown,SampleTown,-

3:Tel:0545848,Mail: bob@hotmail.com
4:克里斯,27岁,SampleTown SampleRoad