R语言如何提取下划线分隔文件名中以model开头的子串
问题原因
- 第一次尝试的正则仅写了
"model",没有匹配同段内后续的字符,因此只能提取到固定的"model"文本,拿不到完整段内容。 - 直接对
str_split()返回的结果用[-3]索引存在两个核心错误:str_split()处理向量输入时返回的是和输入等长的列表结构,直接对列表做索引是在操作列表层级的元素,不是每个文件名拆分后的分段,会导致返回结果长度和原数据框行数不匹配,触发长度报错。- R语言中单中括号的负索引代表排除对应正序位置的元素,不是从末尾倒序取元素,索引逻辑本身不符合取倒数分段的需求。
可行实现方案
方案1:正则一步匹配(最简便,不需要依赖「距末尾段数固定」的条件)
因为目标段是下划线分隔的独立片段,特征是model开头,后面到下一个下划线之前都属于该段内容,直接用正则匹配整段即可:
library(tidyverse) # 测试数据 a = "Vel_Mag_ft_modelExisting_350cfs_blah3.tif" b = "Depth_modelDesign_11000cfs_blah2.tif" tibble(files = c(a,b)) %>% mutate(model_tag = str_extract(files, "model[^_]+"))
运行结果:
# A tibble: 2 × 2 files model_tag <chr> <chr> 1 Vel_Mag_ft_modelExisting_350cfs_blah3.tif modelExisting 2 Depth_modelDesign_11000cfs_blah2.tif modelDesign
正则中[^_]+的含义是匹配1个及以上的非下划线字符,刚好可以把model开头到下一个下划线之前的所有内容完整提取出来。
方案2:拆分后按固定位置取数(适配已知「目标段距末尾分段数固定」的场景)
如果要走拆分逻辑,需要用purrr::map_chr()遍历str_split()生成的列表,对每个拆分后的分段向量单独取倒数位置的元素。示例中目标段都是倒数第3个分段(最后一段是带.tif后缀的blah段,往前数2个就是model开头的段),代码如下:
tibble(files = c(a,b)) %>% mutate( split_list = str_split(files, "_"), model_tag = map_chr(split_list, ~.x[length(.x)-2]) # 倒数第n位 = 总长度减(n-1) ) %>% select(-split_list)
运行结果和方案1完全一致。如果实际数据里目标段距末尾的段数不是3,只要调整偏移值即可:比如取倒数第2段就写length(.x)-1,取倒数第4段就写length(.x)-3。
注意不要直接写
.x[-3],这个写法的含义是删掉拆分结果中正序第3个元素,返回剩下的所有内容,不是取倒数第3个分段。
内容的提问来源于stack exchange,提问作者Brian Fisher
相关产品推荐
相关产品推荐

