2016-08-18 64 views
4

採取下面的代碼來從字符串的列表僅選擇字母數字串:濾波器/ grep的功能行爲奇怪

isValid = function(string){ 
    return(grep("^[A-z0-9]+$", string)) 
} 

strings = c("aaa", "[email protected]", "", "valid") 

print(Filter(isValid, strings)) 

輸出是[1] "aaa" "[email protected]"

爲什麼"valid"沒有輸出,爲什麼輸出的是"[email protected]"

+0

所以邏輯是,如果有任何非字母數字代碼然後不輸出字符串? – thepule

+0

不,重點在於你需要使用'[A-Za-z0-9]',但是我發現它仍然不起作用。 –

+0

使用'strings [grepl(「^ [[:alnum:]] + $」,strings)]' –

回答

2

你可以用這個去相反的方向,並排除任何字符串標點符號,即

isValid <- function(string){ 
    v1 <- string[!string %in% grep('[[:punct:]]', string, value = TRUE)] 
    return(v1[v1 != '']) 
    } 
isValid(strings) 
#[1] "aaa" "valid" 
5

Filter函數接受一個合乎邏輯的載體,你提供的一個數字。使用grepl

isValid = function(string){ 
    return(grepl("^[A-z0-9]+$", string)) 
} 

strings = c("aaa", "[email protected]", "", "valid") 

print(Filter(isValid, strings)) 
[1] "aaa" "valid" 

爲什麼沒有grep工作?這是由於R的數值強制邏輯和Filter的奇怪。

這是發生了什麼,grep("^[A-z0-9]+$", string)正確返回1 4。這是第一個和第四個元素匹配的索引。

但這不是如何Filter的作品。它在每個元素上運行條件爲as.logical(unlist(lapply(x, f)))

所以它跑isValid(strings[1])然後isValid(strings[2])等等。它創造了這個:

[[1]] 
[1] 1 

[[2]] 
integer(0) 

[[3]] 
integer(0) 

[[4]] 
[1] 1 

它當時叫這個列表中unlist得到1 1並把該成一個邏輯向量TRUE TRUE。那麼,到底你有:

strings[which(c(TRUE, TRUE))] 

從而變成

strings[c(1,2)] 
[1] "aaa"   "[email protected]" 

這個故事告訴我們,不要用Filter :)