首页 > 解决方案 > R语言,正则表达式返回一个字符匹配四个字符串

问题描述

在下面的代码中,我将一些文件名读入了 R。文件的实际数量要大得多,但这是一个有代表性的例子。

folder <- here("test_data2")

files <- basename(list.files(path=folder,full.names=TRUE, pattern= "*tab.cut$"))

files <- 
[1] "A_r1_D7__A-Prokka_1.tab.cut"      "AB_r1_D7__A-Prokka_1.tab.cut"     "AB_r2_D7__A-Prokka_1.tab.cut"    
 [4] "AB_r2_D7__B-Prokka_1.tab.cut"     "AB_r2_D7__B-Prokka_10.tab.cut"    "AB_r2_D7__B-Prokka_11.tab.cut"   
 [7] "AB_r2_D7__B-Prokka_12.tab.cut"    "AB_r2_D7__B-Prokka_13.tab.cut"    "AB_r2_D7__B-Prokka_14.tab.cut"   
[10] "AB_r2_D7__B-Prokka_15.tab.cut"    "AB_r2_D7__B-Prokka_16.tab.cut"    "AB_r2_D7__B-Prokka_17.tab.cut"   
[13] "AB_r2_D7__B-Prokka_18.tab.cut"    "AB_r2_D7__B-Prokka_19.tab.cut"    "AB_r2_D7__B-Prokka_2.tab.cut"    
[16] "AB_r2_D7__B-Prokka_3.tab.cut"     "AB_r2_D7__B-Prokka_4.tab.cut"     "AB_r2_D7__B-Prokka_5.tab.cut"    
[19] "AB_r2_D7__B-Prokka_6.tab.cut"     "AB_r2_D7__B-Prokka_7.tab.cut"     "AB_r2_D7__B-Prokka_8.tab.cut"    
[22] "AB_r2_D7__B-Prokka_9.tab.cut"     "ABCD_r1_D14__B-Prokka_1.tab.cut"  "ABCD_r1_D14__B-Prokka_10.tab.cut"
[25] "ABCD_r1_D14__B-Prokka_11.tab.cut" "ABCD_r1_D14__B-Prokka_12.tab.cut" "ABCD_r1_D14__B-Prokka_13.tab.cut"
[28] "ABCD_r1_D14__B-Prokka_14.tab.cut" "ABCD_r1_D14__B-Prokka_15.tab.cut" "ABCD_r1_D14__B-Prokka_16.tab.cut"
[31] "ABCD_r1_D14__B-Prokka_17.tab.cut" "ABCD_r1_D14__B-Prokka_18.tab.cut" "ABCD_r1_D14__B-Prokka_19.tab.cut"
[34] "ABCD_r1_D14__B-Prokka_2.tab.cut"  "ABCD_r1_D14__B-Prokka_3.tab.cut"  "ABCD_r1_D14__B-Prokka_4.tab.cut" 
[37] "ABCD_r1_D14__B-Prokka_5.tab.cut"  "ABCD_r1_D14__B-Prokka_6.tab.cut"  "ABCD_r1_D14__B-Prokka_7.tab.cut" 
[40] "ABCD_r1_D14__B-Prokka_8.tab.cut"  "ABCD_r1_D14__B-Prokka_9.tab.cut"  "ABCD_r1_D14__C-Prokka_1.tab.cut" 
[43] "ABCD_r1_D14__C-Prokka_2.tab.cut"  "ABCD_r1_D14__D-Prokka_1.tab.cut"  "ABCD_r1_D14__D-Prokka_2.tab.cut" 
[46] "ABCD_r1_D14__D-Prokka_3.tab.cut"  "ABCD_r1_D14__D-Prokka_4.tab.cut"  "ABCD_r1_D14__D-Prokka_5.tab.cut" 
[49] "ABCD_r1_D7__A-Prokka_1.tab.cut"   "ACD_r2_D7__C-Prokka_1.tab.cut"    "ACD_r2_D7__C-Prokka_2.tab.cut"   
[52] "ACD_r2_D7__D-Prokka_1.tab.cut"    "ACD_r2_D7__D-Prokka_2.tab.cut"    "ACD_r2_D7__D-Prokka_3.tab.cut"   
[55] "ACD_r2_D7__D-Prokka_4.tab.cut"    "ACD_r2_D7__D-Prokka_5.tab.cut"    "AD_r1_D7__A-Prokka_1.tab.cut"    
[58] "CD_r2_D7__C-Prokka_1.tab.cut"     "CD_r2_D7__C-Prokka_2.tab.cut"

但是假设我想在 list.files() 函数中使用正则表达式来过滤掉前四个字符中不包含“B”的文件。

我认为下面是正确的模式。我一开始想说的\\D{1,4}[B]是返回包含“B”的 1 到 4 个字符的任何字符串。

B_files <- list.files(path=folder,full.names=TRUE, pattern= "\\D{1,4}[B]_([rR][123])_D\\d{1,2}__B-Prokka_\\d{1,2}.tab.cut$")

但这只会返回那些以“AB”开头的文件。那些以“ABCD”开头的不在输出中。

但是,当我通过添加量词稍微更改代码时?,我突然得到一个输出,其中包含以 "ABCD" 和 "AB" 开头的文件:

B_files <- list.files(path=folder,full.names=TRUE, pattern= "\\D{1,4}[B]?_([rR][123])_D\\d{1,2}__B-Prokka_\\d{1,2}.tab.cut$")

有人可以告诉我这里发生了什么吗?我虽然?很懒,这意味着它会搜索最短的字符串。因此,添加 ?量词不应该只返回以“AB”开头的文件吗?

而且,总的来说,我的正则表达式是过滤前一到四个字符中包含字符“B”的文件的正确方法吗?

任何帮助表示赞赏。谢谢!

标签: rregexstringmatchcharacter

解决方案


我们可以使用指定^字符串的开始 ( ) 后跟不包括^方括号内的“B”的字符的模式

"^[^B]{4}.*tab\\.cut$"

我们可以做相反的事情grep

grep("^[^B]{4}.*tab\\.cut$", files, invert = TRUE, value = TRUE)
#[1] "AB_r2_D7__B-Prokka_1.tab.cut"     "ABCD_r1_D14__B-Prokka_11.tab.cut"

数据

files <-  c( "A_r1_D7__A-Prokka_1.tab.cut"  ,  "AB_r2_D7__B-Prokka_1.tab.cut",  "ABCD_r1_D14__B-Prokka_11.tab.cut", "CD_r2_D7__C-Prokka_1.tab.cut"    , "ACD_r2_D7__D-Prokka_4.tab.cut"    )

推荐阅读