跨多行提取SSN的正则表达式及R语言输出方案咨询
提取多行分布SSN的R实现
核心思路
由于SSN分散在SSN:起始行及后续空白开头的行中,先将每行文本合并为完整字符串,再用正则精准匹配所有符合格式的9位数字,最后按需整理输出结构。
代码实现
1. 合并行文本
先把read_lines读取的向量f合并为单一字符串,方便处理跨行内容:
f_text <- paste(f, collapse = "\n")
2. 提取所有SSN
用正向预查正则匹配所有属于SSN块的9位数字,一步到位:
library(stringr) all_ssns <- str_extract_all(f_text, "(?<=SSN:|\\n\\s+)\\d{9}")[[1]]
正则说明:(?<=SSN:|\\n\\s+)限定匹配的9位数字必须紧跟SSN:或换行+空白字符,确保只提取目标SSN。
输出格式处理
最佳实践:单SSN一行的data.frame
这是最便于后续数据处理(筛选、关联等)的结构:
ssn_df <- data.frame(SSN = all_ssns)
按Phase分组的关联data.frame
如果需要绑定SSN所属的Phase:
# 拆分出每个Phase的文本块 phase_blocks <- str_split(f_text, "^-+ Phase \\d+ -+", n = Inf, perl = TRUE)[[1]][-1] # 提取每个Phase对应的SSN并合并 phase_ssn_df <- do.call(rbind, lapply(seq_along(phase_blocks), function(i) { ssns <- str_extract_all(phase_blocks[i], "(?<=SSN:|\\n\\s+)\\d{9}")[[1]] data.frame(Phase = paste0("Phase ", i), SSN = ssns) }))
单单元格逗号分隔的data.frame
若需每个Phase一行、SSN用逗号拼接:
phase_ssn_collapsed_df <- do.call(rbind, lapply(seq_along(phase_blocks), function(i) { ssns <- str_extract_all(phase_blocks[i], "(?<=SSN:|\\n\\s+)\\d{9}")[[1]] data.frame(Phase = paste0("Phase ", i), SSNs = paste(ssns, collapse = ", ")) }))
列表格式
按SSN块分组的列表结构:
ssn_blocks <- str_extract_all(f_text, "SSN:\\s+\\d{9}(\\n\\s+\\d{9})*")[[1]] ssn_list <- lapply(ssn_blocks, function(block) str_extract_all(block, "\\d{9}")[[1]]) names(ssn_list) <- paste0("Phase ", seq_along(ssn_list))
原正则失败原因
你的原正则"SSN:\\s+\\d{9}(\\n\\s\\d{9})?"存在两个问题:
?仅允许匹配最多1个后续SSN行,需改为*(允许0或多个)或+(允许1或多个)- 后续行的空白匹配用
\\s仅匹配单个空白,实际数据是多个空白,需改为\\s+匹配1个及以上空白字符
内容的提问来源于stack exchange,提问作者hackR
相关产品推荐
相关产品推荐

