You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java图书馆项目:换行符检查器未达预期结果的解决问询

Java读取文本行时保留换行分隔符的实现方案

问题场景

我基于Java开发图书馆模拟项目,其中Arrumbadas方法负责返回从未被借出的出版物信息,各条信息以换行符\n分隔。实现逻辑为:通过StringBuilder循环拼接符合条件的信息,每条信息后追加\n,最终转为字符串返回。

为验证输出格式,我编写了hasLineFeed测试方法:用Scanner读取目标字符串,通过hasNextLine()循环调用nextLine()获取每行内容,检查非空行是否以\n结尾。但测试结果显示Has linefeed: false,排查后发现Scanner.hasNextLine()和split()方法都会丢弃换行分隔符,因此需要找到读取文本行时不删除分隔符的方法。

测试样本文本:

"9780547928227","The Hobbit","J.R.R. Tolkien","2","0","High fantasy"
"9780316769174","The Catcher in the Rye","J.R.R. Tolkien","3","0","Coming-of-age fiction"
"9780143124672","Moby-Dick","J.R.R. Tolkien","1","0","Adventure fiction"

测试输出:

"9780547928227","The Hobbit","J.R.R. Tolkien","2","0","High fantasy"
Has linefeed: false

可行解决方案

1. 自定义Scanner分隔符捕获换行符

修改Scanner的分隔规则,使用正向预查正则表达式,让换行符被包含在读取的内容中,而非作为分隔符丢弃:

Scanner scanner = new Scanner(targetString);
// 以换行符前的位置作为分隔点,保留换行符在读取内容里
scanner.useDelimiter("(?=\\n)");
while (scanner.hasNext()) {
    String lineWithNewline = scanner.next();
    // 检查当前行是否以\n结尾
    if (!lineWithNewline.endsWith("\n")) {
        return false;
    }
}
scanner.close();
return true;

2. 逐字符读取(BufferedReader)

使用BufferedReader的read()方法逐字符读取字符串,自行识别换行符,完整保留每行的结尾分隔符:

try (BufferedReader reader = new BufferedReader(new StringReader(targetString))) {
    StringBuilder lineBuilder = new StringBuilder();
    int c;
    while ((c = reader.read()) != -1) {
        lineBuilder.append((char) c);
        // 读取到换行符时,处理当前包含换行的行
        if (c == '\n') {
            String lineWithNewline = lineBuilder.toString();
            if (!lineWithNewline.endsWith("\n")) {
                return false;
            }
            lineBuilder.setLength(0);
        }
    }
    // 处理最后一行(如果原字符串不以\n结尾)
    if (lineBuilder.length() > 0) {
        return false;
    }
} catch (IOException e) {
    e.printStackTrace();
}
return true;

3. 字符串分割结合末尾检查

如果仅为验证格式,可通过split("\n", -1)分割字符串(-1参数保留末尾空字符串,若原字符串以\n结尾),再结合分割结果判断:

String[] lines = targetString.split("\n", -1);
// 除最后一行外,其余行原本应带有\n,最后一行若为空则说明原字符串以\n结尾
for (int i = 0; i < lines.length - 1; i++) {
    int lineEndIndex = lines[i].length() + (i > 0 ? lines[i-1].length() + 1 : 0);
    if (targetString.charAt(lineEndIndex) != '\n') {
        return false;
    }
}
// 若最后一行非空,说明原字符串末尾无\n
return lines[lines.length - 1].isEmpty();

额外优化:简化测试逻辑

由于Arrumbadas方法的拼接逻辑是每条信息后追加\n,其实可以直接验证返回字符串的格式:

  • 若存在符合条件的出版物,字符串应以\n结尾
  • 字符串中不会出现连续两个\n(除非有空的出版物信息,需根据业务判断)

这种方式无需逐行读取,直接通过字符串的endsWith("\n")和contains("\n\n")即可快速验证。


内容的提问来源于stack exchange,提问作者Bayron Viamonte Almonte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:10:38