2011-10-11 154 views
67

我想通過爲每個字符分配不同的值來進行一些使用字符串的二維散步。我打算'彈出'一個字符串的第一個字符,使用它,並重復其餘的字符串。獲取並刪除字符串的第一個字符

我該如何做到這樣?

x <- 'hello stackoverflow' 

我希望能夠做這樣的事情:

a <- x.pop[1] 

print(a) 

'h' 
print(x) 

'ello stackoverflow' 

回答

109

?substring

x <- 'hello stackoverflow' 
substring(x, 1, 1) 
## [1] "h" 
substring(x, 2) 
## [1] "ello stackoverflow" 

具有pop方法,這兩個返回一個值,並且具有更新存儲在x的數據的副作用的想法是非常從面向對象編程的概念。因此,我們可以使用pop方法創建reference class,而不是定義一個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" 
8

使用從stringi

> x <- 'hello stackoverflow' 
> stri_sub(x,2) 
[1] "ello stackoverflow" 
3

該功能除去第一字符:

x <- 'hello stackoverflow' 
substring(x, 2, nchar(x)) 

思想是選擇所有字符從2開始沿x的字符數。當你在單詞或短語中有不同數量的字符時,這很重要。

選擇的第一個字母是微不足道以前的答案:

substring(x,1,1) 
6

substring肯定是最好的,但這裏有一個strsplit的選擇,因爲我還沒有看到一個呢。

> x <- 'hello stackoverflow' 
> strsplit(x, '')[[1]][1] 
## [1] "h" 

或等價

> unlist(strsplit(x, ''))[1] 
## [1] "h" 

你可以paste字符串的其餘部分重新走到一起。

> paste0(strsplit(x, '')[[1]][-1], collapse = '') 
## [1] "ello stackoverflow" 
4

還有str_sub從stringr包

x <- 'hello stackoverflow' 
str_sub(x, 2) # or 
str_sub(x, 2, str_length(x)) 
[1] "ello stackoverflow" 
1

另一種替代方法是使用捕獲子表達式與正則表達式函數regmatchesregexec

# 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" 

,我們可以使用值得信賴的sapply + [方法拔出所需的子字符串。

myFirstStrings <- sapply(myStrings, "[", 2) 
myFirstStrings 
[1] "h" "r" "a" 
mySecondStrings <- sapply(myStrings, "[", 3) 
mySecondStrings 
[1] "ello stackoverflow" "ight back"   "t yah" 
+0

這是一個非常好的竅門,但我認爲這錯過了這個問題。 – pedrosaurio

+0

您需要進一步解釋,因爲它可以產生與其他答案相同的輸出。查看使用'sapply'進行提取的最後一段代碼。如問題中指定的那樣,「彈出」第一個字符是在結果矢量(mySecondStrings)上重複此過程的問題。 – lmo

+0

當然,它與你剛剛添加的額外解釋一起工作,但我仍然覺得它比應該更復雜。 – pedrosaurio

相關問題