需求:基于Base R实现自定义格式字段提取函数fun.extract
实现Base R版
fun.extract函数 核心逻辑
针对分隔符不固定、字段内容可能包含非字母数字、行内容不完整的文本,通过解析format参数指定的字段模板,用正则锚定字段位置,提取目标内容后整理为data.frame。
函数代码
fun.extract <- function(text, format) { # 拆分format为单个字段模板 field_templates <- strsplit(format, ";")[[1]] # 生成合法列名(替换非字母数字为下划线) col_names <- make.names(gsub("[^a-zA-Z0-9]", "_", field_templates)) # 初始化结果容器 result <- setNames(vector("list", length(field_templates)), col_names) # 拆分文本为行 lines <- strsplit(text, "\\n")[[1]] # 逐字段处理 for (i in seq_along(field_templates)) { tpl <- field_templates[i] # 转义模板中的特殊字符(非字母数字) escaped_tpl <- gsub("([^a-zA-Z0-9])", "\\\\\\1", tpl) # 构造两个正则:匹配模板后、模板前的内容 regex_after <- paste0(".*", escaped_tpl, "\\W*(.*?)(\\W+\\w+|$)") regex_before <- paste0("(.*?)\\W*", escaped_tpl, ".*") # 逐行提取内容 extracted <- sapply(lines, function(line) { # 先尝试匹配模板后的内容 res <- sub(regex_after, "\\1", line) if (res != line) { return(trimws(res)) } # 匹配失败则尝试模板前的内容 res <- sub(regex_before, "\\1", line) if (res != line) { return(trimws(res)) } # 都匹配失败返回NA return(NA_character_) }) result[[i]] <- extracted } # 转换为data.frame as.data.frame(result, stringsAsFactors = FALSE) }
代码解释
- 模板解析:将
format按分号拆分后,把模板转为合法列名,避免特殊字符干扰数据框结构。 - 正则适配:对模板中的非字母数字字符转义,生成两个正则分别匹配模板前后的内容,兼容字段在标签前/后的两种常见结构。
- 行处理逻辑:逐行尝试两种正则匹配,成功则返回去空白后的内容,失败则返回NA,适配行内容不完整的场景。
- 结果整理:将所有字段的提取结果组合为
data.frame,保留原始文本的行顺序。
测试示例
# 测试用文本(包含分隔符多样、字段缺失、内容含非字母数字的情况) test_text <- "100-abc value | XYZ)hello-world-note 200 ; value ! DEF)hi_there-note 300 value ; GHI)test-note" # 调用函数 fun.extract(test_text, format = "value;symbol)text-note")
输出:
value symbol_text_note 1 100-abc hello 2 200 hi_there 3 300 <NA> 4 <NA> test
正则细节
escaped_tpl:转义模板中的特殊字符(如)、-),确保正则将其视为普通字符匹配。regex_after:非贪婪匹配模板后的内容,直到遇到下一个单词类标识或行尾,避免捕获无关内容。regex_before:捕获行开头到模板前的所有内容,适配字段在标签左侧的场景。
内容的提问来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

