You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:03:13