使用逗号分隔项的正则表达式

时间:2017-11-09 01:55:50

标签: r regex

我有以下数据集

df <- data.frame(id = c(1,2,3), names = c( "Adam Jones, John David, Maddy Kones", 
"Adam Smith, Maddy Kones, John David", "Maddy Kones, John Peterson, Adam Smith"))

我希望看到行&#34; John&#34;在&#34; Adam&#34;

之后

所以我的输出将是

id                              names
1   Adam Jones, John David, Maddy Kones

我不知道如何使用正则表达式。到目前为止我试过这个

output <- df [grep("Adam" [^,]* "John", df$names),]

2 个答案:

答案 0 :(得分:4)

这里的一个基本R方法是使用grepl和一个合适的模式:

Adam\b[^,]*,\\s*John.*

这表示匹配Adam后跟单词边界以及直到第一个逗号的任何内容,紧接着John作为下一个术语。我们没有任何丑陋的边缘情况,因为如果约翰必须跟随亚当,这意味着总会有一个逗号分隔这两个名字。

<强>代码:

df[grepl("Adam\\b[^,]*,\\s*John.*", df$names), ]

Demo

答案 1 :(得分:3)

<强>更新

当没有“亚当”或“约翰”时,原始解决方案没有给出预期的答案。例如,对于此数据框

df
#  id                                  names
#1  1    Adam Jones, John David, Maddy Kones
#2  2    Adam Smith, Maddy Kones, John David
#3  3 Maddy Kones, John Peterson, Adam Smith
#4  4                 Adam Smith, Ronak Shah 

使用原始解决方案,我们将输出为

#   id                               names
#1   1 Adam Jones, John David, Maddy Kones
#NA NA                                <NA>

要更正此问题,我们会添加isTRUE函数的附加检查,该功能会忽略此类NA并仅向我们提供TRUE个元素

df[sapply(strsplit(df$names, ","), function(x) 
       isTRUE(grep("John", x) - grep("Adam", x) == 1)), ]

#  id                               names
#1  1 Adam Jones, John David, Maddy Kones

原始答案

另一种选择是将所有names分开到,并使用grep来检查“John”和“Adam”出现的位置,并选择它们之间的区别是1(如“约翰”跟随“亚当”)。

df[sapply(strsplit(df$names, ","), function(x) 
                      grep("John", x) - grep("Adam", x)) == 1, ]

#id                               names
#1  1 Adam Jones, John David, Maddy Kones