2016-08-18 40 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 :)