我有一组错误命名的文件。文件名如下。
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))
答案 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组(通过gsubfn
在x
方法中访问该值):
(?:\\D*\\d+){n}
- n 的出现次数
\\D*
- 除数字\\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")