如何使用Java基于正则表达式将文件拆分为标记

3

我有一个文件,格式如下,记录是由换行符分隔的,但有些记录内部也有换行符,就像下面这样。我需要单独获取每个记录并进行处理。该文件可能有几兆字节大小。

 <?aaaaa>
 <?bbbb
     bb>
 <?cccccc>

我有这段代码:

 FileInputStream fs = new FileInputStream(FILE_PATH_NAME);
 Scanner scanner = new Scanner(fs);
 scanner.useDelimiter(Pattern.compile("<\\?"));
 if (scanner.hasNext()) {
     String line = scanner.next();
     System.out.println(line);
 } 
 scanner.close();

但是我得到的结果已经去掉了开头的<\?:

aaaaa>
bbbb
   bb>
cccccc>

我知道 Scanner 会消耗与定界符模式匹配的任何输入。我能想到的唯一办法就是手动将定界符模式添加回每个记录中。
有没有一种方法可以不删除定界符模式?
3个回答

5

仅在前面有">"字符时,才在换行处断开:

scanner.useDelimiter("(?<=>)\\R"); // Note you can pass a string directly

\R 是一个独立于系统的换行符
(?<=>) 是一个“向后查找”,它断言(不消耗)前一个字符是 >

此外,它很酷,因为 <=> 看起来像达斯·维达的TIE战斗机


我测试了更多的记录,这种方法使一些记录在同一行上。你能帮忙吗? - jlp
@jlp 你的意思是像这样缺少一个换行符吗 "<?aaa>\n<?bbb><?ccc>\n<?ddd>" 在 bbb 和 ccc 之间? - Bohemian
顺便说一下,如果是这种情况,处理起来很容易 - 只需要在正则表达式的结尾添加 ? 即可。 - Bohemian
@Bohemian,抱歉,我有另一个问题。如果数据是这样的"<aaaa><bbbb><cccc>",它们之间没有空格或换行符,我该如何编写正则表达式才能将它们分成三行,像<aaaa>,然后<bbbb>和<cccc>。请告诉我是否应该为此问题创建另一篇帖子。谢谢。 - jlp
根据先前的评论,@jlp请将“?”添加到正则表达式中:“scanner.useDelimiter("(?<=>)\R?");”。这样可以让换行符成为可选项,但如果有,它仍然会被消耗。 - Bohemian

1

我假设你想在所有地方忽略换行符'\n'

我会把整个文件读入一个 String,然后删除 String 中的所有 '\n'。这个问题涉及的代码部分看起来是这样的:

String fileString = new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
fileString = fileString.replace("\n", "");
Scanner scanner = new Scanner(fileString);
...  //your code

随时提出您可能有的任何进一步问题!


文件可能有几MB大小,不确定将整个文件存储到字符串中是否会引起任何问题。 - jlp
@jlp 我不会担心文件大小达到几兆,但你说得对,这种方法不太适合大规模应用。 - Todd Sewell

0
这是使用 StringBuilder 的一种方法:
public static void main(String[] args) throws FileNotFoundException {
    Scanner in = new Scanner(new File("C:\\test.txt"));
    StringBuilder builder = new StringBuilder();

    String input = null;
    while (in.hasNextLine() && null != (input = in.nextLine())) {
        for (int x = 0; x < input.length(); x++) {
            builder.append(input.charAt(x));
            if (input.charAt(x) == '>') {
                System.out.println(builder.toString());
                builder = new StringBuilder();
            }
        }
    }

    in.close();
}

输入:

 <?aaaaa>
 <?bbbb
     bb>
 <?cccccc>

输出:

 <?aaaaa>
 <?bbbb     bb>
 <?cccccc>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接