R语言文件名数字补零函数异常问题求助
R语言文件名数字补零问题修正
问题说明
我已实现PadNumbers函数,输入c(1, 2, 30)可输出c("01", "02", "30")。现需实现ex02PadFiles函数对文件名中的数字补零,期望输入c("podcast_ep1.mp3", "podcast_ep3.mp3", "podcast_ep22.mp3")时输出c("podcast_ep01.mp3", "podcast_ep03.mp3", "podcast_ep22.mp3"),但当前代码输出最后一个文件名为"podcast_ep022.mp3",不符合预期。
原代码如下:
PadNumbers <- function(numbers) { assertIntegerish(numbers, min.len = 0, lower = 0) strnumbers <- as.character(numbers) numbers <- as.numeric(gsub(".*?(\\d+).*", "\\1", strnumbers)) if (any(!is.na(numbers))) { maxdigits <- max(nchar(as.character(numbers)), na.rm = TRUE) } else { maxdigits <- 0 } paddednumbers <- sprintf(paste0("%0", maxdigits, "d"), numbers) paddednumbers[is.na(numbers)] <- NA return(paddednumbers) }
ex02PadFiles <- function(filenames) { assertCharacter(filenames, any.missing = FALSE, len = length(filenames)) if (length(filenames) == 0) { return(character(0)) } paddednumbers <- ex01PadNumbers(as.integer(gsub("\\D", "", filenames))) paddedfilenames <- gsub("(\\d+)(\\.\\w+)$", "0\\1\\2", filenames) return(paddedfilenames) }
问题分析
- 原
ex02PadFiles中的gsub操作是直接在数字前加0,没有依据所有文件名中数字的最大长度动态补零,导致长数字被错误添加多余的0。 - 函数中调用的
ex01PadNumbers是笔误,实际应为已实现的PadNumbers。 gsub("\\D", "", filenames)提取数字的方式过于宽泛,若文件名中存在其他非目标数字会出错。
修正方案
下面是修正后的ex02PadFiles函数,复用你已有的PadNumbers逻辑,精准处理文件名中的数字补零:
基于Base R的实现
ex02PadFiles <- function(filenames) { assertCharacter(filenames, any.missing = FALSE, len = length(filenames)) if (length(filenames) == 0) { return(character(0)) } # 精准提取文件名后缀前的连续数字 num_matches <- regexpr("\\d+(?=\\.\\w+$)", filenames, perl = TRUE) num_strs <- regmatches(filenames, num_matches) numbers <- as.integer(num_strs) # 使用已实现的PadNumbers处理数字补零 padded_numbers <- PadNumbers(numbers) # 将补零后的数字替换回原文件名 regmatches(filenames, num_matches) <- padded_numbers return(filenames) }
基于stringr包的实现(更简洁)
library(stringr) ex02PadFiles <- function(filenames) { assertCharacter(filenames, any.missing = FALSE, len = length(filenames)) if (length(filenames) == 0) { return(character(0)) } # 提取后缀前的数字 num_strs <- str_extract(filenames, "\\d+(?=\\.\\w+$)") numbers <- as.integer(num_strs) # 补零处理 padded_numbers <- PadNumbers(numbers) # 逐个替换原数字为补零后的版本 padded_filenames <- mapply(function(fn, old, new) { str_replace(fn, paste0(old, "(?=\\.\\w+$)"), new) }, filenames, num_strs, padded_numbers) return(as.character(padded_filenames)) }
测试验证
运行以下代码:
ex02PadFiles(c("podcast_ep1.mp3", "podcast_ep3.mp3", "podcast_ep22.mp3"))
输出结果为:
[1] "podcast_ep01.mp3" "podcast_ep03.mp3" "podcast_ep22.mp3"
完全符合预期。
内容的提问来源于stack exchange,提问作者tong tong
相关产品推荐
相关产品推荐

