是否可以在以下向量上使用正则表达式:
u<-c("first1","sec2","thir33","fourth4","fifth25","sixth16",
"seven7","eight8","nine9","ten10","eleven11")
获得:
[1] "first.1" "sec.2" "thir3.3" "fourth.4" "fifth2.5" "sixth1.6" "seven.7" "eight.8"
[9] "nine.9" "ten.10" "eleven.11"
这就像我得到的那样接近:
gsub("([A-Za-z]*)([1]{0,1})([0-9]$)","\\1\\.\\2\\3",u)
#[1] "first.1" "sec.2" "thir3.3" "fourth.4" "fifth2.5" "sixth.16" "seven.7" "eight.8" "nine.9" "ten.10"
#[11] "eleven.11"
注意第六个元素不正确:“six.16”应为“six1.6”。
答案 0 :(得分:4)
我没有看到内部正则表达式方法“知道”或有权访问向量中的位置,但是当然可以将其传入并在模式中使用其“as.character”强制值。
sapply(seq_along(u), function(x) sub(
paste("(^.+)(", as.character(x), "$)", sep=""),
"\\1.\\2", u[x]) )
[1] "first.1" "sec.2" "thir3.3" "fourth.4" "fifth2.5" "sixth1.6" "seven.7" "eight.8" "nine.9"
[10] "ten.10" "eleven.11"
答案 1 :(得分:1)
这不是特别漂亮,但您可以通过以下步骤一步完成:
gsub("([A-Za-z]+)(10|11)?(?:(\\d)(\\d))?([0-9]{0,1}?)$","\\1\\3\\.\\2\\4\\5",u)
或者,您可以将其分解为几个步骤。首先取一位数,然后分别处理2位数的情况。
v <- gsub("([A-Za-z]+)(\\d)$","\\1.\\2",u)
v <- gsub("([A-Za-z]+)(10|11)$","\\1.\\2",v)
v <- gsub("([A-Za-z]+\\d)(\\d)$","\\1.\\2",v)
答案 2 :(得分:1)
使用DWin的答案作为跳跃点,你可以通过知道元素1:9,10:99,100:999等等都可以获得一些速度(假设你真正的问题解决了更长的向量)以相同的方式。
所以,获取一些更大的数据
u<-c("first1","sec2","thir33","fourth4","fifth25","sixth16",
"seven7","eight8","nine9","ten10","eleven11")
u[12:101981]<-NA
set.seed(1)
for(i in 12:101981)u[i]<-paste0(paste(sample(c(LETTERS,1:9),5),collapse=""),i)
lengthu<-length(u)
maxLength<-nchar(lengthu)
theStart<-10^(seq_len(maxLength)-1)
theEnd<-c(theStart[-1]-1,lengthu)
然后使用sapply
而不是u
中的每个元素,而是使用长度为maxLength
的序列
tempans<-sapply(seq_len(maxLength),function(x){
sub(paste0("(^.*)(\\d{",x,"})"),"\\1.\\2",u[theStart[x]:theEnd[x]])
})
tail(unlist(tempans))
# [1] "DWY96.101976" "UWFCO.101977" "UR5L8.101978" "XBQ9V.101979" "48MTI.101980"
# [6] "75LIS.101981"
head(unlist(tempans))
# [1] "first.1" "sec.2" "thir3.3" "fourth.4" "fifth2.5" "sixth1.6"