30

我在 R 中有以下向量,我想找到所有包含 A 和 B 但不包含数字 2 的字符串。

vec1<-c("A_cont_1", "A_cont_12", "B_treat_8", "AB_cont_22", "cont_21_Aa")

以下不起作用:

grep("A|B|!2", vec1)

它给了我所有的字符串:

[1] 1 2 3 4 5

此示例也是如此:

grep("A|B|-2", vec1)

什么是正确的语法?

4

5 回答 5

38

你可以用一个相当简单的正则表达式来做到这一点:

grep("^[^2]*[AB][^2]*$", vec1)

换句话说,它的意思是:

  • ^匹配字符串的开头
  • [^2]*匹配“2”之外的任何内容,零次或多次
  • [AB]匹配“A”或“B”
  • [^2]*匹配“2”之外的任何内容,零次或多次
  • $匹配字符串的结尾
于 2013-08-14T19:13:25.733 回答
23

我会使用两个grep电话:

intersect(grep("A|B",vec1),grep("2",vec1,invert=TRUE))
#[1] 1 3
于 2013-08-14T18:13:22.677 回答
22

OP,你的尝试非常接近,试试这个:

grep('^(A|B|[^2])*$', vec1)
于 2013-08-14T21:12:59.957 回答
4

grep通常不能很好地在一次调用中进行肯定和否定搜索。您也许可以使用复杂的正则表达式使其工作,但您最好只这样做:

 grep '[AB]' somefile.txt | grep -v '2'

对应的 R 将是:

grep("2", grep("A|B", vec1, value = T), invert = T)
于 2013-08-14T18:00:35.163 回答
1

我扩展了@eddi 提供的答案。我已经在 R 中对其进行了测试,它对我有用。我更改了您示例中的最后一个变量,因为它们都包含 A|B。

# Create the vector from the OP with one change
vec1<-c("A_cont_1", "A_cont_12", "B_treat_8", "AB_cont_22", "cont_21_dd")

然后我运行了以下代码。它将告诉您应该从 grep 的每个部分获得哪些结果。

首先,告诉我哪些列包含 A 或 B

> grepl("A|B", vec1)
[1] TRUE TRUE TRUE TRUE FALSE

现在告诉我哪些列包含“2”

> grepl("2", vec1)
[1] FALSE TRUE FALSE TRUE TRUE

我们想要的索引是 2,4

> grep("2", grep("A|B", vec1, value = T))
[1] 2 4

完毕!

于 2019-04-09T20:17:42.027 回答