R dplyr正则匹配删除非开头含指定子串的列报错求解
报错原因
你写的后行断言语法本身没有错误,报错核心原因是dplyr::matches()默认使用R内置的TRE正则引擎,该引擎不支持零宽断言(包含你用到的反向/后行断言(?<!...)语法),因此正则编译阶段直接抛出错误。
可行解决方案
以下三种方法都可以实现需求,按需选择即可:
- 方法1:开启Perl兼容正则支持,保留你原本的后行断言写法
给matches()传入perl = TRUE参数,切换到支持零宽断言的PCRE引擎即可正常运行:library(dplyr) df <- data.frame(bar = rnorm(1), foo1 = rnorm(1), bar_foo1 = rnorm(1), bar_foo1_bat = rnorm(1)) df %>% select(-matches("(?<!^)foo1", perl = TRUE)) - 方法2:改用基础正则实现,无需切换引擎
需求本质是匹配*foo1出现在非开头位置*,等价于「foo1前面至少存在1个任意字符」,用基础正则.+foo1就可以实现,不需要用到断言:df %>% select(-matches(".+foo1")) - 方法3:用dplyr内置的选择助手组合实现,完全不用写正则
先移除所有包含foo1的列,再把列名开头为foo1的列加回来,可读性更高,不容易出现正则写错的问题:df %>% select(-contains("foo1"), starts_with("foo1"))
以上三种方法运行后都能得到预期输出,仅保留bar和foo1两列。
注:你之前写的
(?<!^).*foo1.*里的.*是多余的,matches()本身就是检测字符串中是否存在匹配的子串,不需要额外写前后通配符。
内容的提问来源于stack exchange,提问作者socialscientist
相关产品推荐
相关产品推荐

