R语言中使用正则表达式提取文件名信息失败的求助
我来帮你一步步排查问题哈,咱们从你的正则表达式和函数用法逐个分析:
问题分析与修正方案
1. 先看gsub()的潜在问题
你的gsub正则.*-ASG_\\d{2}_本身逻辑是对的——它会匹配从文件名开头到-ASG_两位数字_的整个前缀,替换为空后应该得到00020。如果没得到预期结果,大概率是变量赋值的小问题:比如有没有确保fext确实是去掉.tab后缀的字符串?可以先打印fext确认下:
print(fext) # 应该输出:"TC2L6C_2020-08-14_1516_6C-ASG_29_00020"
如果变量没问题,重新运行gsub就能得到正确结果。
2. str_extract()提取失败的核心原因
你写的正则(?<=-ASG_\\d+)([^_])*(?=\\.tab)有两个关键bug:
- 正向零宽断言
(?<=-ASG_\\d+)匹配的是-ASG_29之后的位置,但这个位置紧接着是下划线_,而你用[^_]*是匹配「非下划线的字符」,第一个字符就不匹配,自然提取不到内容。 - 括号
([^_])*是多余的,不需要给单个字符分组,写成[^_]*就够了。
修正后的str_extract()写法
根据你的需求(提取-ASG_数字_后面到.tab前面的内容),可以用这两种更精准的正则:
# 方法1:匹配-ASG_数字_之后到.tab之前的所有字符 P_num <- stringr::str_extract(fname, "(?<=-ASG_\\d+_)[^\\.]+") # 方法2:明确匹配数字串(如果目标内容固定是数字) P_num <- stringr::str_extract(fname, "(?<=-ASG_\\d+_)\\d+(?=\\.tab)")
运行任意一种都会得到00020,完全符合预期。
3. 为什么str_view()能匹配,但提取不行?
你用stringr::str_view(fext, ".*-ASG_\\d+_", match = TRUE)能看到高亮匹配,是因为这个正则匹配的是前缀部分,而str_view只是帮你确认前缀的匹配范围,但这不代表提取逻辑是对的——提取需要精准定位你要的目标内容,而不是匹配它的前缀。
额外的稳健方案(不用正则)
如果你的文件名格式是固定的(用下划线分隔各个字段),其实可以不用正则,直接拆分字符串,更直观也不容易出错:
# 拆分去掉后缀的文件名,按下划线分割成列表 parts <- stringr::str_split(fext, "_")[[1]] # 取最后一个元素就是目标内容 P_num <- parts[length(parts)]
内容的提问来源于stack exchange,提问作者rottweiller
相关产品推荐
相关产品推荐

