Java如何提取文本文件中跨多行的房间描述并合并为单个元素存储
调整思路
你原有代码的问题是没有建立描述和所属房间的对应关系,只是全局收集所有非关键字行,自然无法按房间拆分存储。你可以通过添加收集状态标记的方式实现需求,逻辑如下:
- 新增布尔类型的状态标记,标记当前是否处于收集描述内容的阶段
- 新增字符串临时变量,存储当前正在拼接的单条房间描述
- 遇到以
Description:开头的行时,开启收集状态,先把冒号后的内容存入临时变量 - 处于收集状态时,逐行检查:
- 如果当前行包含
exits :,就把exits :之前的内容拼到临时变量中,结束收集状态,将临时变量的内容存入描述结果列表,清空临时变量 - 如果当前行不包含
exits :,直接把内容拼到临时变量中即可
- 如果当前行包含
另外你现有方法的返回值都是void,收集的结果都存在方法内部的局部变量里,外部无法调用,建议修改为返回对应结果列表。
修改后的完整代码
package MiniTextBasedGame; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; public class fileParser { public static String[] getLines(File file){ String contents = null; Path path = file.toPath(); String[] lines = null; try { contents = Files.readString(path, StandardCharsets.ISO_8859_1); } catch (IOException ex) { System.out.println("文件读取错误"); return new String[0]; } lines = contents.split("\n"); return lines; } // 提取房间ID列表 public static List<String> getRoomID(String[] array){ List<String> idList = new ArrayList<>(); for (String str: array) { str = str.trim(); if(str.startsWith("ID =")){ String temp = str.split("=")[1].trim(); idList.add(temp); } } return idList; } // 提取房间名称列表 public static List<String> getRoomName(String[] array){ List<String> nameList = new ArrayList<>(); for (String str: array) { str = str.trim(); if(str.startsWith("name =")){ String temp = str.split("=")[1].trim(); nameList.add(temp); } } return nameList; } // 提取按房间分组的描述列表,一个元素对应一个房间的完整描述 public static List<String> getRoomDescription(String[] array){ List<String> descList = new ArrayList<>(); // 收集状态标记 boolean isCollectingDesc = false; // 存储当前正在拼接的单条描述 StringBuilder currentDesc = new StringBuilder(); for (String str: array) { // 去除首尾空白避免格式干扰 String line = str.trim(); if(line.isBlank()) continue; // 遇到Description行,开始收集 if(line.startsWith("Description:")){ isCollectingDesc = true; // 先把Description:后面的内容加进去 currentDesc.append(line.substring(12).trim()); continue; } // 处于收集状态 if(isCollectingDesc){ // 检查当前行是否包含exits字段 int exitIndex = line.indexOf("exits :"); if(exitIndex != -1){ // 把exits之前的内容拼进去 currentDesc.append(" ").append(line, 0, exitIndex).trimToSize(); // 结束收集 isCollectingDesc = false; descList.add(currentDesc.toString().trim()); // 清空临时缓存 currentDesc.setLength(0); }else{ // 普通描述行,直接拼接 currentDesc.append(" ").append(line); } } } return descList; } // 提取出口列表 public static List<String> getExits(String[] array){ List<String> exitList = new ArrayList<>(); for (String str: array) { str = str.trim(); if(str.startsWith("exits :")){ String temp = str.split(":")[1].trim(); exitList.add(temp); } } return exitList; } // 测试方法 public static void main(String[] args) { File file = new File("替换为你的测试文件实际路径"); String[] lines = getLines(file); List<String> descList = getRoomDescription(lines); // 打印每个房间的描述 for (int i = 0; i < descList.size(); i++) { System.out.println("房间" + i + "描述:" + descList.get(i)); System.out.println("---------------------------"); } } }
代码说明
- 调整了所有字段提取方法的返回值为List,收集的结果可以直接在外部调用使用
- 兼容了描述和exits字段在同一行的特殊情况(比如你测试文件里ID=1的房间)
- 拼接的时候自动加空格避免多行内容连在一起,同时自动去除多余空白
- 用startsWith替换原来的contains判断,避免描述内容里出现关键字时误判
- 新增了main测试方法,替换文件路径后可直接运行查看效果
内容的提问来源于stack exchange,提问作者Ted Tony
相关产品推荐
相关产品推荐

