Answers:
请参阅?substring
。
x <- 'hello stackoverflow'
substring(x, 1, 1)
## [1] "h"
substring(x, 2)
## [1] "ello stackoverflow"
具有pop
既返回值又具有更新存储在其中的数据的副作用的方法的想法在x
很大程度上是面向对象编程的概念。因此pop
,我们可以定义带有方法的引用类,而不是定义对字符向量进行操作的函数pop
。
PopStringFactory <- setRefClass(
"PopString",
fields = list(
x = "character"
),
methods = list(
initialize = function(x)
{
x <<- x
},
pop = function(n = 1)
{
if(nchar(x) == 0)
{
warning("Nothing to pop.")
return("")
}
first <- substring(x, 1, n)
x <<- substring(x, n + 1)
first
}
)
)
x <- PopStringFactory$new("hello stackoverflow")
x
## Reference class object of class "PopString"
## Field "x":
## [1] "hello stackoverflow"
replicate(nchar(x$x), x$pop())
## [1] "h" "e" "l" "l" "o" " " "s" "t" "a" "c" "k" "o" "v" "e" "r" "f" "l" "o" "w"
从stringi
包使用此功能
> x <- 'hello stackoverflow'
> stri_sub(x,2)
[1] "ello stackoverflow"
另一种选择是将捕获子表达式与正则表达式函数regmatches
和一起使用regexec
。
# the original example
x <- 'hello stackoverflow'
# grab the substrings
myStrings <- regmatches(x, regexec('(^.)(.*)', x))
这将返回整个字符串,第一个字符,并在长度为1的列表中显示“弹出”结果。
myStrings
[[1]]
[1] "hello stackoverflow" "h" "ello stackoverflow"
等同于list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x))))
。也就是说,它包含所需元素的超集以及完整字符串。
加法sapply
将使该方法适用于长度> 1的字符向量。
# a slightly more interesting example
xx <- c('hello stackoverflow', 'right back', 'at yah')
# grab the substrings
myStrings <- regmatches(x, regexec('(^.)(.*)', xx))
这将返回一个列表,其中匹配的完整字符串作为第一个元素,而匹配的子表达式()
作为以下元素捕获。因此,在正则表达式中'(^.)(.*)'
,(^.)
匹配第一个字符,然后(.*)
匹配其余字符。
myStrings
[[1]]
[1] "hello stackoverflow" "h" "ello stackoverflow"
[[2]]
[1] "right back" "r" "ight back"
[[3]]
[1] "at yah" "a" "t yah"
现在,我们可以使用trusty sapply
+ [
方法提取所需的子字符串。
myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back" "t yah"
sapply
用于提取的最后代码块。如问题中所述,“弹出”第一个字符是对所得向量(mySecondStrings)重复此过程的问题。