Язык R, регулярное выражение для возврата односимвольных соответствий в четырехсимвольной строке - PullRequest
0 голосов
/ 12 апреля 2020

В приведенном ниже коде я прочитал некоторые имена файлов в 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] возвращает любую строку символов от 1 до 4 символов, которая содержит «B».

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", так и с «АБ»:

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"?

И, в целом, является ли мое регулярное выражение правильным способом go для фильтрации тех файлов, которые содержат символ «B» в пределах от первого до четырех символов?

Любая помощь приветствуется. Спасибо!

Ответы [ 2 ]

2 голосов
/ 12 апреля 2020

Мы можем использовать шаблон, определяющий начало (^) строки, за которой следуют следующие символы, которые не включают '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"

data

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"    )
1 голос
/ 12 апреля 2020
dat <- c("A_r1_D7.cut", "AB_r1_D7.cut", "ABCD_r1_D14.cut",
         "ACD_r2_D7.cut", "CD_r2_D7.cut", "B.c")

Вы можете написать:

grep("^.{0,3}B", dat, value=T)

Демо

или

grep("^(?=.{0,3}B)", dat, value=T, perl=T)

Демо

Оба возвращают

[1] "AB_r1_D7.cut"    "ABCD_r1_D14.cut" "B.c"

Обратите внимание, что последний должен использовать механизмы регулярных выражений PCRE, так как механизм по умолчанию не поддерживает положительных указателей (или вообще обходов).

...