R data.table提取同时包含多个指定子字符串的行的实现方法
实现同时包含多个指定子串的行筛选方法
正则没有直接的&逻辑运算符来实现「同时包含多个子串」的匹配,你可以用以下几种方式实现需求,均不限制子串的出现顺序:
方法1:使用正向预查正则表达式
这是最简洁的单表达式写法,需要开启perl正则支持:
# 第一个示例的筛选写法 df[grepl("(?=.*Gua)(?=.*rd)", df$position, perl = TRUE), ]
其中(?=.*子串)是正向肯定预查语法,代表无论子串在什么位置,都必须存在,多个预查规则并列就代表所有规则都要满足。
方法2:多匹配条件逻辑与组合
可读性更高,不需要记忆复杂正则语法,适合子串数量少的场景:
df[grepl("Gua", df$position) & grepl("rd", df$position), ]
如果用data.table自带的%like%运算符,写法更简洁:
df[position %like% "Gua" & position %like% "rd", ]
方法3:批量匹配多子串(适合子串数量多/动态生成的场景)
如果需要同时匹配的子串数量很多,或者子串是动态生成的,可以用批量判断的方式,不用手动拼接正则或条件:
# 把需要匹配的所有子串存为向量 match_words <- c("Gua", "rd") # 筛选同时包含所有子串的行 df[rowSums(sapply(match_words, \(x) grepl(x, df$position))) == length(match_words), ]
以上方法对大数据集的处理效率都很高,不会有性能问题。
补充场景:跨表匹配的实现
针对你补充的两个表关联筛选的需求,参考写法如下:
# 筛选df1的position2列同时包含Gua和rd,提取df2对应的行 df2[grepl("(?=.*Gua)(?=.*rd)", df1$position2, perl = TRUE), .(player, points)] # 用%like%的写法 df2[df1$position2 %like% "Gua" & df1$position2 %like% "rd", .(player, points)]
不管子串顺序是Guard还是rdGua,以上所有方法都会正常匹配。
内容的提问来源于stack exchange,提问作者Kipkoech Rotich
相关产品推荐
相关产品推荐

