我有mystring
这个分隔符"_"
。这里的条件是,如果有两个或更多分隔符,我想在第二个分隔符处拆分,如果只有一个分隔符,我想在".Recal"
分割并得到result
,如下所示。
mystring<-c("MODY_60.2.ReCal.sort.bam","MODY_116.21_C4U.ReCal.sort.bam","MODY_116.3_C2RX-1-10.ReCal.sort.bam","MODY_116.4.ReCal.sort.bam")
结果
"MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"
答案 0 :(得分:11)
您可以使用gsubfn
library(gsubfn)
f <- function(x,y,z) if (z=="_") y else strsplit(x, ".ReCal", fixed=T)[[1]][[1]]
gsubfn("([^_]+_[^_]+)(.).*", f, mystring, backref=2)
# [1] "MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"
这允许您有两个以上“_”的情况,并且您希望在第二个上分割,例如,
mystring<-c("MODY_60.2.ReCal.sort.bam",
"MODY_116.21_C4U.ReCal.sort.bam",
"MODY_116.3_C2RX-1-10.ReCal.sort.bam",
"MODY_116.4.ReCal.sort.bam",
"MODY_116.4_asdfsadf_1212_asfsdf",
"MODY_116.5.ReCal_asdfsadf_1212_asfsdf", # split by second "_", leaving ".ReCal"
"MODY")
gsubfn("([^_]+_[^_]+)(.).*", f, mystring, backref=2)
# [1] "MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"
# [5] "MODY_116.4" "MODY_116.5.ReCal" "MODY"
在函数中,f
,x
是原始字符串,y
和z
是下一个匹配项。因此,如果z
不是“_”,那么它继续通过替代字符串进行拆分。
答案 1 :(得分:5)
使用stringr
包:
str_extract(mystring, '.*?_.*?(?=_)|^.*?_.*(?=\\.ReCal)')
[1] "MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"
它也适用于两个以上的分隔符。
答案 2 :(得分:5)
Perl / PCRE具有分支重置功能,可让您在使用不同备选方案捕获组时重用组号,并被视为一个捕获组。
IMO,当你想提供不同的选择时,这个功能很优雅。
x <- c('MODY_60.2.ReCal.sort.bam', 'MODY_116.21_C4U.ReCal.sort.bam',
'MODY_116.3_C2RX-1-10.ReCal.sort.bam', 'MODY_116.4.ReCal.sort.bam',
'MODY_116.4_asdfsadf_1212_asfsdf', 'MODY_116.5.ReCal_asdfsadf_1212_asfsdf', 'MODY')
sub('^(?|([^_]*_[^_]*)_.*|(.*)\\.ReCal.*)$', '\\1', x, perl=T)
# [1] "MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"
# [5] "MODY_116.4" "MODY_116.5.ReCal" "MODY"
答案 3 :(得分:4)
gsub('^(.*\\.\\d+).*','\\1',mystring)
[1] "MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"
答案 4 :(得分:2)
^([^_\\n]*_[^_\\n]*)(?:_.*|\\.ReCal[^_]*)$
您可以使用gsub
而不使用任何复杂的正则表达式。只需用\\1
替换。请参阅演示。
答案 5 :(得分:2)
稍长一点,但需要较少的正规表达知识:
library(stringr)
indx <- str_locate_all(mystring, "_")
for (i in seq_along(indx)) {
if (nrow(indx[[i]]) == 1) {
mystring[i] <- strsplit(mystring[i], ".ReCal")[[1]][1]
} else {
mystring[i] <- substr(mystring[i], start = 1, stop = indx[[i]][2] - 1)
}
}
答案 6 :(得分:0)
gregexpr
可以在字符串中搜索模式并提供位置。
首先,我们使用gregexpr
在_
的每个元素中查找所有mystring
的位置。然后,我们遍历该输出并提取_
的每个元素内第二mystring
的索引。如果没有第二个_
,它将返回一个NA
(在下面的示例中选中inds
)。
此后,我们可以根据提取的索引使用substr
提取相关部分,或者,如果存在NA
,我们可以将字符串拆分为.ReCal
并仅保留第一部分。
inds = sapply(gregexpr("_", mystring, fixed = TRUE), function(x) x[2])
ifelse(!is.na(inds),
substr(mystring, 1, inds - 1),
sapply(strsplit(mystring, ".ReCal"), '[', 1))
#[1] "MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"