grep使用具有多个模式的字符向量

时间:2011-09-29 12:48:53

标签: r regex

我正在尝试使用grep来测试字符串向量是否存在于另一个向量中,并输出存在的值(匹配模式)。

我有一个这样的数据框:

FirstName Letter   
Alex      A1
Alex      A6
Alex      A7
Bob       A1
Chris     A9
Chris     A6

我在“Letter”列中找到了一个字符串模式向量,例如:c("A1", "A9", "A6")

我想检查模式向量中的任何字符串是否出现在“Letter”列中。如果是,我想要输出唯一值。

问题是,我不知道如何将grep用于多种模式。我试过了:

matches <- unique (
    grep("A1| A9 | A6", myfile$Letter, value=TRUE, fixed=TRUE)
)

但它给了我0场比赛,这不是真的,有什么建议吗?

10 个答案:

答案 0 :(得分:243)

除了@ Marek关于不包括fixed==TRUE的评论之外,您还需要在正则表达式中不要使用空格。它应该是"A1|A9|A6"

你还提到有很多模式。假设它们在向量中

toMatch <- c("A1", "A9", "A6")

然后,您可以直接从此创建正则表达式。

matches <- unique (grep(paste(toMatch,collapse="|"), 
                        myfile$Letter, value=TRUE))

答案 1 :(得分:24)

好的答案,但不要忘记来自dplyr的filter()

patterns <- c("A1", "A9", "A6")
>your_df
  FirstName Letter
1      Alex     A1
2      Alex     A6
3      Alex     A7
4       Bob     A1
5     Chris     A9
6     Chris     A6

result <- filter(your_df, grepl(paste(patterns, collapse="|"), Letter))

>result
  FirstName Letter
1      Alex     A1
2      Alex     A6
3       Bob     A1
4     Chris     A9
5     Chris     A6

答案 2 :(得分:7)

根据Brian Digg的帖子,这里有两个有用的过滤列表功能:

#Returns all items in a list that are not contained in toMatch
#toMatch can be a single item or a list of items
exclude <- function (theList, toMatch){
  return(setdiff(theList,include(theList,toMatch)))
}

#Returns all items in a list that ARE contained in toMatch
#toMatch can be a single item or a list of items
include <- function (theList, toMatch){
  matches <- unique (grep(paste(toMatch,collapse="|"), 
                          theList, value=TRUE))
  return(matches)
}

答案 3 :(得分:5)

不确定这个答案是否已经出现......

对于问题中的特定模式,您可以通过一次grep()调用来执行此操作,

grep("A[169]", myfile$Letter)

答案 4 :(得分:4)

您是否尝试过match()charmatch()功能?

使用示例:

match(c("A1", "A9", "A6"), myfile$Letter)

答案 5 :(得分:4)

添加到Brian Diggs的答案。

使用grepl的另一种方法是返回包含所有值的数据框。

toMatch <- myfile$Letter

matches <- myfile[grepl(paste(toMatch, collapse="|"), myfile$Letter), ]

matches

Letter Firstname
1     A1      Alex 
2     A6      Alex 
4     A1       Bob 
5     A9     Chris 
6     A6     Chris

也许有点清洁......也许?

答案 6 :(得分:2)

带走空间。所以:

matches <- unique(grep("A1|A9|A6", myfile$Letter, value=TRUE, fixed=TRUE))

答案 7 :(得分:2)

这应该有效:

grep(pattern = 'A1|A9|A6', x = myfile$Letter)

或更简单地说:

myfile$Letter %like% 'A1|A9|A6'

答案 8 :(得分:1)

使用sapply

 patterns <- c("A1", "A9", "A6")
         df <- data.frame(name=c("A","Ale","Al","lex","x"),Letters=c("A1","A2","A9","A1","A9"))



   name Letters
1    A      A1
2  Ale      A2
3   Al      A9
4  lex      A1
5    x      A9


 df[unlist(sapply(patterns, grep, df$Letters, USE.NAMES = F)), ]
  name Letters
1    A      A1
4  lex      A1
3   Al      A9
5    x      A9

答案 9 :(得分:-1)

我建议写一个小脚本并用Grep进行多次搜索。我从来没有找到过寻找多种模式的方法,相信我,我看了!

就像这样,你的shell文件,带有嵌入字符串:

 #!/bin/bash 
 grep *A6* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";
 grep *A7* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";
 grep *A8* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";

然后键入myshell.sh运行。

如果你想在命令行上传入字符串,可以这样做,使用shell参数 - 这是bash表示法btw:

 #!/bin/bash 
 $stingtomatch = "${1}";
 grep *A6* "${stingtomatch}";
 grep *A7* "${stingtomatch}";
 grep *A8* "${stingtomatch}";

等等。

如果要匹配很多模式,可以将其置于for循环中。