在字符串中插入字符,条件是从开头和结尾开始的字符数

sim*_*one 3 r regex-lookarounds

我有一个字符串列表,如

myvar
[1] "VT" "AK" "AL2" "CA24" "NY12" 
[6] "AZ6" "WY4"
Run Code Online (Sandbox Code Playgroud)

我想在所有包含3个字符的字符串中的第二个字符后插入字符"0",并在所有包含两个字符的字符串的末尾插入"01",以获得输出

myvar
[1] "VT01" "AK01" "AL02" "CA24" "NY12" 
[6] "AZ06" "WY04"
Run Code Online (Sandbox Code Playgroud)

我认为我可以使用正则表达式前瞻和后瞻在一行中做到这一点,但我不能比这更进一步:

sub('(?<=.{2})(?=.{1})', '0', myvar, perl=T)

myvar
[1] "VT" "AK" "AL002" "CA024" "NY012" 
[6] "AZ06" "WY04"
Run Code Online (Sandbox Code Playgroud)

任何帮助将非常感激,

西蒙娜

akr*_*run 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"
Run Code Online (Sandbox Code Playgroud)

或者使用gsubfn.我们ifelse为那些没有任何数字元素并粘贴1的元素创建条件.我们匹配gsubfn(\\d+)中的数字部分,用格式替换它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"
Run Code Online (Sandbox Code Playgroud)

或者稍微更紧凑的版本sub用于将1附加到没有数字部分的元素

 gsubfn('\\d+', ~sprintf('%02d', as.numeric(x)) ,sub('(?<=[A-Z])$', '1', myvar, perl=TRUE))
 #[1] "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"
Run Code Online (Sandbox Code Playgroud)

或者在没有外观的情况下使其更加紧凑,

gsubfn('\\d+', ~sprintf('%02d', as.numeric(x)), sub('(\\D+)$', '\\11', myvar))
#[1] "VT01" "AK01" "AL02" "CA24" "NY12" "AZ06" "WY04"
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案有效,我感谢akrun分享它,但我不认为我应该接受它,因为问题是询问使用正则表达式前瞻和后观的一个班轮.那是错的吗? (3认同)

Ten*_*bai 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"
Run Code Online (Sandbox Code Playgroud)

使用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))
Run Code Online (Sandbox Code Playgroud)

目标是获得4个字符条目的向量,因此对于4个字符(myvar[nchar(myvar)<4])下的所有条目,沿着长度为4的左边填充"1"减去实际条目长度打印它们.

可能有一种with避免冗余调用的方法,myvar[nchar(myvar)<4]但由于我不习惯,我实际上在挖掘.