在一个较长的字符串中,隔离出字母串

8

有没有一种方法可以隔离字符串中按字母顺序排列的部分?

换句话说,如果你有一个像这样的字符串:hjubcdepyvb

你能只提取按字母表顺序排列的部分吗?:bcde

我考虑过使用is.unsorted()函数,但我不确定如何仅将其应用于字符串的部分。

3个回答

8

以下是一种将文本转换为ASCII码再转回的方法:

input <- "hjubcdepyvb"
spl_asc <- as.integer(charToRaw(input))       # Convert to ASCII
d1 <- diff(spl_asc) == 1                      # Find sequences
filt <- spl_asc[c(FALSE, d1) | c(d1, FALSE)]  # Only keep sequences (incl start and end)
rawToChar(as.raw(filt))                       # Convert back to character

#[1] "bcde"

请注意,这将连接任何按字母顺序排列的部分。
例如,如果输入是"abcxasdicfgaqwe",则输出将是abcfg
如果您想要为每个连续字符串获取单独的向量,则可以执行以下操作。
input <- "abcxasdicfgaqwe"
spl_asc <- as.integer(charToRaw(input))
d1 <- diff(spl_asc) == 1
r <- rle(c(FALSE, d1) | c(d1, FALSE))                   # Find boundaries
cm <- cumsum(c(1, r$lengths))                           # Map these to string positions
substring(input, cm[-length(cm)], cm[-1] - 1)[r$values] # Extract matching strings

最后,我不得不想出一种使用正则表达式的方法:

input <- c("abcxasdicfgaqwe", "xufasiuxaboqdasdij", "abcikmcapnoploDEFgnm",
           "acfhgik")
(rg <- paste0("(", paste0(c(letters[-26], LETTERS[-26]),
                           "(?=", c(letters[-1], LETTERS[-1]), ")", collapse = "|"), ")+."))

#[1] "(a(?=b)|b(?=c)|c(?=d)|d(?=e)|e(?=f)|f(?=g)|g(?=h)|h(?=i)|i(?=j)|j(?=k)|
#k(?=l)|l(?=m)|m(?=n)|n(?=o)|o(?=p)|p(?=q)|q(?=r)|r(?=s)|s(?=t)|t(?=u)|u(?=v)|
#v(?=w)|w(?=x)|x(?=y)|y(?=z)|A(?=B)|B(?=C)|C(?=D)|D(?=E)|E(?=F)|F(?=G)|G(?=H)|
#H(?=I)|I(?=J)|J(?=K)|K(?=L)|L(?=M)|M(?=N)|N(?=O)|O(?=P)|P(?=Q)|Q(?=R)|R(?=S)|
#S(?=T)|T(?=U)|U(?=V)|V(?=W)|W(?=X)|X(?=Y)|Y(?=Z))+."

regmatches(input, gregexpr(rg, input, perl = TRUE))
#[[1]]
#[1] "abc" "fg" 
#
#[[2]]
#[1] "ab" "ij"
#
#[[3]]
#[1] "abc" "nop" "DEF"
#
#[[4]]
#character(0)

这个正则表达式可以识别连续的大写或小写字母(但不包括大小写混合的情况)。如示例所示,它适用于字符向量,并生成一个包含所有匹配项的向量列表。如果没有找到匹配项,则输出为character(0)


4

使用整数因子转换:

input <- "hjubcdepyvb"
d1 <- diff(as.integer(factor(unlist(strsplit(input, "")), levels = letters))) == 1
filt <- c(FALSE, d1) | c(d1, FALSE)
paste(unlist(strsplit(input, ""))[filt], collapse = "")
# [1] "bcde"

3
myf = function(x){
    x = unlist(strsplit(x, ""))
    ind = charmatch(x, letters)
    d = c(0, diff(ind))
    d[d !=1] = 0
    d = d + c(sapply(1:(length(d)-1), function(i) {
        ifelse(d[i] == 0 & d[i+1] == 1, 1, 0)
    }
    ), 0)
    d = split(seq_along(d)[d!=0], with(rle(d), rep(seq_along(values), lengths))[d!=0])
    return(sapply(d, function(a) paste(x[a], collapse = "")))
}

myf(x = "hjubcdepyvblltpqrs")
#     2      4 
#"bcde" "pqrs" 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接