如何在R中递归将文本文件读取为嵌套列表?
在R中解析带大括号的文本为嵌套列表
我明白你想要解析一段用{}标记嵌套结构的文本,转换成R中的嵌套列表。之前的递归函数因为几个逻辑问题没能生成预期的嵌套结构,我来帮你修正并实现需求。
原始文本与预期结果
首先看你的目标输入文本(按行拆分后):
date=1638.1.16 player="BYZ" savegame_version={ first=1 second=25 third=1 forth=0 name="England" } mod_enabled={ "Large Font" "Large Tooltips" }
你期望得到的嵌套列表结构:
[[1]] [1] "date=1638.1.16" [[2]] [1] "player=\"BYZ\"" [[3]] [[3]][[1]] [1] "savegame_version={" [[3]][[2]] [1] "\tfirst=1" [[3]][[3]] [1] "\tsecond=25" [[3]][[4]] [1] "\tthird=1" [[3]][[5]] [1] "\tforth=0" [[3]][[6]] [1] "\tname=\"England\"" [[3]][[7]] [1] "}" [[4]] [[4]][[1]] [1] "mod_enabled={" [[4]][[2]] [1] "\t\"Large Font\"" [[4]][[3]] [1] "\t\"Large Tooltips\"" [[4]][[4]] [1] "}"
原函数的问题分析
你的初始递归函数存在几个关键问题:
- 递归结果未被捕获:调用
list_create()递归时,没有将返回的嵌套列表添加到当前的temp_list中,导致嵌套层级丢失 - 索引计算错误:
vector[i+1:length(vector)]的写法不符合R的运算符优先级,会被解析为i + (1:length(vector)),完全偏离预期的索引范围 - 未跳过已处理元素:递归处理完嵌套内容后,外层循环会重复处理已经被递归处理过的行
- 带
{的行未被加入列表:遇到{时直接进入递归,没有先把当前行(比如savegame_version={)加入结果
修正后的递归解析函数
我重新写了一个递归函数,用环境变量跟踪当前处理的索引(实现传引用效果),正确处理嵌套逻辑:
library(stringr) parse_nested_list <- function(vec) { # 创建环境变量跟踪当前索引,避免传值修改的局限 idx_env <- new.env() idx_env$current <- 1 recursive_parse <- function() { result <- list() while (idx_env$current <= length(vec)) { line <- vec[idx_env$current] idx_env$current <- idx_env$current + 1 if (str_detect(line, "\\{")) { # 先将带{的行加入子列表,再递归处理后续内容 sub_list <- list(line) sub_list <- c(sub_list, recursive_parse()) # 将嵌套子列表加入当前层级结果 result <- c(result, list(sub_list)) } else if (str_detect(line, "\\}")) { # 遇到}时,将该行加入子列表并返回,结束当前递归层级 result <- c(result, line) return(result) } else { # 普通行直接加入当前层级结果 result <- c(result, line) } } return(result) } return(recursive_parse()) }
使用方法
- 读取并预处理文本:将你的文本文件读取为字符向量,去除空行(如果有):
# 读取文本文件 raw_text <- readLines("your_file.txt") # 过滤空行 raw_text <- raw_text[raw_text != ""]
- 调用解析函数:
nested_list <- parse_nested_list(raw_text) # 查看结果结构 str(nested_list)
如果你手动构造测试文本,比如:
raw_text <- c( "date=1638.1.16", "player=\"BYZ\"", "savegame_version={", "\tfirst=1", "\tsecond=25", "\tthird=1", "\tforth=0", "\tname=\"England\"", "}", "mod_enabled={", "\t\"Large Font\"", "\t\"Large Tooltips\"", "}" ) nested_list <- parse_nested_list(raw_text) print(nested_list)
运行后就能得到你预期的嵌套列表结构。
内容的提问来源于stack exchange,提问作者Isak Hietala
相关产品推荐
相关产品推荐

