替换字符串中的第n个数字

时间:2018-05-05 09:08:50

标签: r regex

我有一组错误命名的文件。文件名如下。

Generation_Flux_0_Model_200.txt
Generation_Flux_101_Model_43.txt
Generation_Flux_11_Model_3.txt

我需要通过在现有数字上加1来替换第二个数字(型号)。所以正确的名字将是

Generation_Flux_0_Model_201.txt
Generation_Flux_101_Model_44.txt
Generation_Flux_11_Model_4.txt

这是我写的代码。我想知道如何指定数字的位置(用新数字替换字符串中的第二个数字)?

reNameModelNumber <- function(modelName){

  #get the current model number
  modelNumber = as.numeric(unlist(str_extract_all(modelName, "\\d+"))[2])

  #increment it by 1
  newModelNumber = modelNumber + 1

  #building the new name with gsub 
  newModelName = gsub("  regex ", newModelNumber, modelName) 

  #rename
  file.rename(modelName, newModelName)


}


reactionModels = list.files(pattern = "^Generation_Flux_\\d+_Model_\\d+.txt$")

sapply(reactionFiles, function(x) reNameModelNumber(x))

4 个答案:

答案 0 :(得分:8)

我们可以使用gsubfn增加1.捕获数字((\\d+))  然后是字符串的. and 'txt' at the end ( $`),并通过向其添加1替换它

library(gsubfn)
gsubfn("(\\d+)\\.txt$", ~ as.numeric(x) + 1, str1)
#[1] "Generation_Flux_0_Model_201"  "Generation_Flux_101_Model_44"
#[3] "Generation_Flux_11_Model_4"  

数据

str1 <- c("Generation_Flux_0_Model_200.txt", "Generation_Flux_101_Model_43.txt", 
                   "Generation_Flux_11_Model_3.txt")

答案 1 :(得分:6)

回答这个问题,如果你想在字符串中增加一定数量,你可以使用

> library(gsubfn)
> nth = 2
> reactionFiles <- c("Generation_Flux_0_Model_200.txt", "Generation_Flux_101_Model_43.txt", "Generation_Flux_11_Model_3.txt")
> gsubfn(paste0("^((?:\\D*\\d+){", nth-1, "}\\D*)(\\d+)"), function(x,y,z) paste0(x, as.numeric(y) + 1), reactionFiles)
[1] "Generation_Flux_0_Model_201.txt"  "Generation_Flux_101_Model_44.txt" "Generation_Flux_11_Model_4.txt"  

nth这里是要增加的数字块的编号。

模式详情

  • ^((?:\\D*\\d+){n}\\D*) - 捕获第1组(通过gsubfnx方法中访问该值):
    • (?:\\D*\\d+){n} - n 的出现次数
      • \\D* - 除数字
      • 以外的0个或更多字符
      • \\d+ - 1+位数
    • \\D* - 0+非数字
  • (\\d+) - 捕获第2组(通过gsubfn y方法访问该值):一个或多个数字

答案 2 :(得分:4)

使用base-R。

data <- c( # Just an example
  "Generation_Flux_0_Model_200.txt",
  "Generation_Flux_101_Model_43.txt",
  "Generation_Flux_11_Model_3.txt"
)

fixNameModel <- function(data){
  n <- length(data)

  # get the current model number and increment it by 1
  newn = as.integer(sub(".+_(\\d+)\\.txt", "\\1", data)) + 1L

  #building the new name with gsub
  newModelName <- vector(mode = "character", length = n)
  for (i in 1:n) {
    newModelName[i] <- gsub("\\d+\\.txt$", paste0(newn[i], ".txt"), data[i])
  }
  newModelName
}

fixNameModel(data)
[1] "Generation_Flux_0_Model_201.txt"  "Generation_Flux_101_Model_44.txt"
[3] "Generation_Flux_11_Model_4.txt"  

您现在可以执行file.rename(modelName, fixNameModel(modelName))

之类的操作

编辑

这是一个更整洁的版本,但做出更强有力的假设:

fixNameModel2 <- function(data) {
  sapply(
    strsplit(data, "_|\\."), 
    function(x) {
      x[5] <- as.integer(x[5]) + 1L
      x <- paste0(x, collapse = "_")
      gsub("_txt", ".txt", x, fixed = TRUE)
    } 
  )
}

答案 3 :(得分:2)

假设数字总是出现在扩展名之前,如评论中所提到的,这里是另一个基础R解决方案,它稍微简单一点。

sapply(regmatches(tmp, regexec("\\d+(?=\\.)", tmp, perl=TRUE), invert=NA),
       function(x) paste0(c(x[1], as.integer(x[2]) + 1L, x[3]), collapse=""))

返回

[1] "Generation_Flux_0_Model_201.txt"  "Generation_Flux_101_Model_44.txt"
[3] "Generation_Flux_11_Model_4.txt" 

regexec,其中invert = NA索引列表,其中每个列表元素是与完整部分匹配的索引,匹配元素作为第二个索引元素返回。 regmatches获取此信息并返回一个字符向量列表,这些字符向量会在匹配项中分解原始字符串。将此列表提供给sapply,将第二个元素转换为整数并递增。然后粘贴结果以返回原子向量。

正则表达式&#34; \ d +(?= \。)&#34;使用perl外观,&#34;(?= \。)&#34;,寻找点而不捕获它,但使用&#34; \ d +&#34;来捕获数字。

数据

tmp <- c("Generation_Flux_0_Model_200.txt", "Generation_Flux_101_Model_43.txt", 
"Generation_Flux_11_Model_3.txt")