我们可以概括Edward和rawr的 idea .
> spl_pat <- \(x, p) {
+ stopifnot(all(is.na(p) | p >= 0))
+ if (any(is.na(p))) return(x) ## compatibility w/ strsplit()
+ if (identical(p, NULL)) p <- 1 ## compatibility w/ strsplit()
+ .spl <- \(x) {
+ pat <- rep_len(p, len=1 + nchar(x)/2)
+ start <- cumsum(c(1, pat[-length(pat)]))
+ stop <- cumsum(pat)
+ Filter(nzchar, substring(x, start, stop))
+ }
+ if (length(x) > 1L) lapply(x, .spl) else .spl(x)
+ }
使用
Single strings, 100:
> spl_pat('ABCDEFG', 2:1)
[1] "AB" "C" "DE" "F"
> spl_pat('ABCDEFG', c(1, 4))
[1] "A" "BCDE" "F" "G"
> spl_pat('ABCDEFG', c(0, 4))
[1] "ABCD" "EFG"
> spl_pat('ABCDEFG', 1:1e3)
[1] "A" "BC" "DEF" "G"
> spl_pat('ABCDEFG', 2)
[1] "AB" "CD" "EF" "G"
> spl_pat('ABCDEFG', 1)
[1] "A" "B" "C" "D"
> spl_pat('ABCDEFG', 0)
character(0)
> spl_pat('ABCDEFG', NA)
[1] "ABCDEFG"
> spl_pat('ABCDEFG', NULL)
[1] "A" "B" "C" "D"
Multiple strings, 100:
> spl_pat(c('ABCDEFG', 'ABCDEFGHIJ'), 2:1)
[[1]]
[1] "AB" "C" "DE" "F"
[[2]]
[1] "AB" "C" "DE" "F" "GH" "I"
Different patterns:
> Vectorize(spl_pat)(c('ABCDEFG', 'ABCDEFGHIJ'), list(2:1, 1:2))
$ABCDEFG
[1] "AB" "C" "DE" "F"
$ABCDEFGHIJ
[1] "A" "BC" "D" "EF" "G" "HI"
> Vectorize(spl_pat)(c('ABCDEFG', 'ABCDEFGHIJ', 'ABCDEFGHIJ'), list(2:1, 1:2, 0))
$ABCDEFG
[1] "AB" "C" "DE" "F"
$ABCDEFGHIJ
[1] "A" "BC" "D" "EF" "G" "HI"
$ABCDEFGHIJ
[1] ""
p < 0 probably wouldn't make sense, would it?:
> spl_pat('ABCDEFG', -1)
Error in spl_pat("ABCDEFG", -1) : all(is.na(p) | p >= 0) is not TRUE