我有一个字符串列表,例如
myvar
[1] "VT" "AK" "AL2" "CA24" "NY12"
[6] "AZ6" "WY4"
我想在所有包含3个字符的字符串中的第二个字符后插入字符“0”,并在所有包含两个字符的字符串的末尾插入“01”,以获得输出< / p>
myvar
[1] "VT01" "AK01" "AL02" "CA24" "NY12"
[6] "AZ06" "WY04"
我以为我可以使用正则表达式前瞻和后瞻在一行中完成此操作,但我无法比这更进一步:
sub('(?<=.{2})(?=.{1})', '0', myvar, perl=T)
myvar
[1] "VT" "AK" "AL002" "CA024" "NY012"
[6] "AZ06" "WY04"
非常感谢任何帮助,
西蒙
答案 0 :(得分:6)
我们可以使用sub
提取数字部分,将字符串转换为numeric
类,将NA值(从强制)更改为1,并使用sprintf
粘贴非数字(sub('\\d+', ...)
)和格式化的数字部分。
v1 <- as.numeric(sub('\\D+', '', myvar))
v1[is.na(v1)] <- 1
sprintf('%s%02d', sub('\\d+', '', myvar),v1)
#[1] "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"
或使用gsubfn
。我们为那些没有任何数字元素并粘贴1的元素创建ifelse
条件。我们匹配gsubfn
(\\d+
)中的数字部分,将其格式化为{ {1}}。
sprintf
或稍微更紧凑的版本使用 library(gsubfn)
gsubfn('\\d+', ~sprintf('%02d', as.numeric(x)),
ifelse(!grepl('\\d+', myvar), paste0(myvar, 1), myvar))
#[1] "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"
将1附加到那些没有数字部分的元素
sub
或者在没有外观的情况下使其更加紧凑,
gsubfn('\\d+', ~sprintf('%02d', as.numeric(x)) ,sub('(?<=[A-Z])$', '1', myvar, perl=TRUE))
#[1] "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"
答案 1 :(得分:5)
关于静态剪切和粘贴的想法:
paste0(substr(myvar, 0, 2), sub("00", "01", gsub(" ", "0", sprintf("% 2s", substr(myvar, 3, 4)))))
# [1] "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"
使用substr获取最后2个字符,将它们填充为2个字符,将空格替换为0,然后将00替换为01,粘贴2个第一个字符并获得结果。
一个衬垫(没有正则表达式,因为它们不需要,并且除非使用复杂的选择后再替换为什么,否则对确定替换尺寸非常有用):
myvar[nchar(myvar)<4] <- paste0(myvar[nchar(myvar)<4],sprintf(paste0("%0",4-nchar(myvar[nchar(myvar)<4]),"i"),1))
目标是获得4个字符条目的向量,因此对于4个字符(myvar[nchar(myvar)<4]
)下的所有条目,沿着0左边填充&#34; 1&#34;长度为4减去实际入口长度。
with
可能有办法避免对myvar[nchar(myvar)<4]
的多余调用,但由于我不习惯,我实际上在挖掘。
答案 2 :(得分:3)
另一种选择(可能是一个(长)班轮......):
mapply(function(x, dc_x){
if(nchar(x)<4) paste0(dc_x[1], "0", ifelse(length(dc_x)-1, dc_x[2], "1")) else x
},
x=myvar, dc_x=strsplit(myvar, "(?<=^.{2})", perl=T))
# VT AK AL2 CA24 NY12 AZ6 WY4
# "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"
<强>解释强>
dc_x
是一个向量列表,一个用于myvar
的每个元素,第一个项目是myvar
中相应项目的前2个字符。因此,对于少于4个字符的元素,您将使用&#34; 01&#34;粘贴2个第一个字符。如果只有2个字符或者&#34; 0&#34;和字符串的其余部分,如果有超过2个字符。
答案 3 :(得分:2)
您可以将sub或gsub命令的输出作为输入放到另一个sub或gsub命令中。
myvar <- c("VT", "AK", "AL2", "CA24", "NY12",
"AZ6", "WY4")
sub("^(.{2})$", "\\101", sub("^(.{2})(.)$", "\\10\\2", myvar))
# [1] "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"