如何按分隔符拆分TXT文件内容并添加层级制表符?
解决XML风格TXT文件的层级格式化问题
你的需求本质是要解析嵌套的标签结构,根据标签的嵌套层级添加对应数量的制表符,同时保持每个标签(含内容的完整标签)单独成行。之前的代码只是简单按>拆分字符串,完全没有处理标签的开闭逻辑和层级关系,所以无法得到期望的格式化效果。
正确实现思路
- 读取完整文件内容:因为输入可能是单行的紧凑结构,逐行读取会丢失上下文,所以先把整个文件内容读成一个字符串。
- 清理冗余空白:去除内容中多余的空格、换行等,避免干扰标签匹配。
- 正则匹配标签单元:用正则表达式识别三种标签单元:带内容的完整元素、单独的开始标签、单独的结束标签。
- 跟踪嵌套层级:维护一个层级变量,遇到开始标签时层级加1,遇到结束标签时层级减1,根据当前层级输出对应数量的制表符。
完整Java代码实现
import java.io.BufferedReader; import java.io.FileReader; import java.util.regex.Matcher; import java.util.regex.Pattern; public class XmlFormatter { public static void main(String[] args) throws Exception { // 读取文件内容到字符串 BufferedReader br = new BufferedReader(new FileReader("input.txt")); StringBuilder contentBuilder = new StringBuilder(); String line; while ((line = br.readLine()) != null) { contentBuilder.append(line); } br.close(); String rawContent = contentBuilder.toString(); // 清理多余空白(保留标签内的内容空格) String cleanedContent = rawContent.replaceAll(">\\s+<", "><").trim(); // 正则表达式匹配三种标签单元 String regex = "(<([a-zA-Z]+)>([^<]*)</\\2>)|(<([a-zA-Z]+)>)|(</([a-zA-Z]+)>)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(cleanedContent); int indentLevel = 0; while (matcher.find()) { String fullMatch = matcher.group(); // 判断匹配的是哪种标签单元 if (matcher.group(1) != null) { // 带内容的完整元素,比如<name>xyz</name> printWithIndent(fullMatch, indentLevel); } else if (matcher.group(4) != null) { // 单独的开始标签,比如<company> printWithIndent(fullMatch, indentLevel); indentLevel++; } else if (matcher.group(6) != null) { // 单独的结束标签,比如</address> indentLevel--; printWithIndent(fullMatch, indentLevel); } } } // 辅助方法:根据层级输出制表符和内容 private static void printWithIndent(String content, int level) { for (int i = 0; i < level; i++) { System.out.print("\t"); } System.out.println(content); } }
代码说明
- 文件读取:把整个文件内容读入
StringBuilder,避免逐行读取的局限性。 - 空白清理:用
replaceAll(">\\s+<", "><")去掉标签之间的多余空格,同时保留标签内内容的空格(比如ABC PQR里的空格)。 - 正则匹配:通过正则精准识别三种标签单元,确保不会拆分带内容的完整元素。
- 层级控制:遇到开始标签时先输出再提升层级,遇到结束标签时先降低层级再输出,带内容的元素直接按当前层级输出。
运行这段代码后,就能得到你期望的格式化输出。
内容的提问来源于stack exchange,提问作者Vinay




