如何用正则从字符串倒数第n个下划线到最后一个下划线间截取子串?
解决方案:从字符串末尾截取目标子串
针对你的需求,这里提供几种从末尾着手的可行思路和代码实现(基于R语言):
思路1:拆分后截取(直观易理解)
把字符串按下划线拆分成片段,直接截取需要的部分再拼接:
string <- "trash_trash_trash_keep_keep_keep_trash.trash" # 拆分字符串为列表 split_parts <- strsplit(string, "_")[[1]] # 截取第4个到倒数第2个元素(跳过前3个trash和最后1个trash.trash) target_parts <- split_parts[4:(length(split_parts)-1)] # 拼接成目标字符串 result <- paste(target_parts, collapse = "_")
运行后直接得到:"keep_keep_keep"
思路2:一步到位的反向正则匹配
利用正则从末尾定位,精准匹配目标区域。这个正则会匹配最后一个下划线之前、且被下划线包裹的连续内容(对应示例里的keep_keep_keep):
string <- "trash_trash_trash_keep_keep_keep_trash.trash" # 用regmatches提取匹配结果 result <- regmatches(string, regexpr("(?<=_)[^_]+_[^_]+_[^_]+(?=_[^_]+$)", string, perl = TRUE))
或者用替换的方式,保留目标部分:
result <- sub(".*_([^_]+_[^_]+_[^_]+)_[^_]+$", "\\1", string)
思路3:分步替换(通用型更强)
如果不确定中间目标部分有多少个下划线,只需要去掉末尾的_xxx片段,再剥离开头的冗余内容:
string <- "trash_trash_trash_keep_keep_keep_trash.trash" # 第一步:去掉末尾的"_trash.trash" temp <- sub("_[^_]+$", "", string) # 第二步:去掉开头所有内容直到最后一个下划线 result <- sub(".*_", "", temp)
这种方法不管中间目标是2个还是N个下划线连接的片段,都能正确提取。
你之前用的^(?:[^_]*){3}(.+)_正则失效,是因为原字符串末尾没有下划线,(.+)_要求匹配到下划线结尾,自然无法匹配成功。从末尾反向匹配就能避开这个问题。
内容的提问来源于stack exchange,提问作者jack kelly
相关产品推荐
相关产品推荐

