Использование отрицательной обратной связи в R

#r #regex-lookarounds

#r #поиск по регулярным выражениям

Вопрос:

У меня есть эти строки в папке. Предположим, что в этой папке есть другие похожие файлы.

  [3] "/farm/chickens_industrial_meat_location_df.csv"   
 [4] "farm/goats_grassland_meat_location_df.csv" 
  

Я пытаюсь извлечь файлы со строкой location_df , исключая файлы со строкой chickens amp; location_df .

Я думал, что смогу сделать это, набрав: list.files(pattern = "location_df(?<!(chickens))"

Насколько я понимаю, использование отрицательного поиска приведет к удалению строк, которые имеют chickens . Чего я не понимаю в regex здесь и каково решение моей проблемы.

Ответ №1:

Вариант с grepl был бы

 str1[!grepl('chickens_.*location_df', str1) amp; grepl('location_df', str1)]
#[1] "farm/goats_grassland_meat_location_df.csv"
  

Или более упрощенная версия была бы

 str1[!grepl('chickens_', str1) amp; grepl('location_df', str1)]
  

данные

 str1 <- c("/farm/chickens_industrial_meat_location_df.csv",
        "farm/goats_grassland_meat_location_df.csv" )
  

Ответ №2:

 > list.files(pattern = "location_df")
[1] "chickens_industrial_meat_location_df.csv" "goats_grassland_meat_location_df.csv"    

> setdiff(list.files(pattern = "location_df"), list.files(pattern = "chickens"))
[1] "goats_grassland_meat_location_df.csv"

> setdiff(list.files(pattern = "location_df"), list.files(pattern = "goats"))
[1] "chickens_industrial_meat_location_df.csv"
  

Согласно R-helpfile для регулярных выражений, «… функции, которые используют регулярные выражения (часто с использованием grep), включают apropos, browseEnv, help.search, list.files и ls. Все они будут использовать расширенные регулярные выражения.» (ERE).

Чтение вышеизложенного указывает на то, что функции list.files() и list.dirs() не реализуют поисковые решения, которые обычно доступны с помощью регулярных выражений, совместимых с Perl (PCRE). Небольшая подсказка заключается в том, что R-helpfile для list.files() / list.dirs() не включает эту опцию perl=TRUE .

Таким образом, вместо поисковых запросов приведенный выше код использует setdiff() , чтобы помочь вам запросить каталог. Конечно, в приведенном выше коде два «токена» регулярных выражений, которые вы ищете, могут отображаться в любом порядке, но вы можете помочь себе, выполнив поиск «location_df.csv» или «location_df.csv $» (поскольку расширение «.csv» должно быть в конце имени файла, а утверждение $ -zerowidth аналогичным образом привязало бы шаблон к концу строки). Вы также могли бы попробовать использовать ^ для привязки «цыплят» или «коз» к началу строки. Объединение всего этого дает приведенный ниже код:

 > setdiff(list.files(pattern = "location_df.csv$"), list.files(pattern = "^chickens"))
[1] "goats_grassland_meat_location_df.csv"

> setdiff(list.files(pattern = "location_df.csv$"), list.files(pattern = "^goats"))
[1] "chickens_industrial_meat_location_df.csv"
  

https://stat.ethz.ch/R-manual/R-devel/library/base/html/regex.html
https://www.r-project.org/