Извлечь строку между последним вхождением символа и фиксированным выражением - PullRequest
2 голосов
/ 20 марта 2019

У меня есть набор строк, таких как

mystring
[1] "RData/processed_AutoServico_cat.rds"
[2] "RData/processed_AutoServico_cat_master.rds"

Я хотел бы получить строку между последним вхождением подчеркивания "_" и ".rds"

Я могусделать это в два шага

str_extract(mystring, '[^_]+$') %>% # get everything after the last '_'
    str_extract('.+(?=\\.rds)') # get everything that preceeds '.rds' 
[1] "cat"    "master"

И есть другие способы, которыми я могу это сделать.

Есть ли какое-либо одно выражение регулярного выражения, которое бы получило все символы между последним появлением универсальногосимвол и другое фиксированное выражение?

Регулярные выражения, такие как

str_extract(mystring, '[^_]+$(?=\\.rds)')
str_extract(mystring, '(?<=[_]).+$(?=\\.rds)')

, не работают

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

Шаблон [^_]+$(?=\.rds) соответствует 1+ символам, отличным от _, до конца строки, а затем требуется .rds после конца строки, что невозможно, это регулярное выражение никогда не будет соответствовать ни одной строке. (?<=[_]).+$(?=\.rds) аналогичен в этом отношении, он не будет соответствовать ни одной строке, он просто начнет совпадать, как только найдет первый _, и достигнет конца строки, пытаясь найти .rds после него.

Вы можете использовать

str_extract(mystring, "[^_]+(?=\\.rds$)")

Или, базовый эквивалент R:

regmatches(s, regexpr("[^_]+(?=\\.rds$)", s, perl=TRUE)) 

См. Демонстрационную версию regex

Детали шаблона

  • [^_]+ - 1 или более символов, отличных от _
  • (?=\.rds$) - положительный прогноз, требующий .rds в конце строки непосредственно справа от текущего местоположения.

См. График Regulex :

enter image description here

1 голос
/ 20 марта 2019

С помощью base R мы получаем basename и используем sub для захвата слова перед ., за которым следуют символы, которые не являются . до конца ($) строкии заменить на обратную ссылку (\\1) захваченной группы

sub(".*_(\\w+)\\.[^.]+$", "\\1", basename(mystring))
#[1] "cat"    "master"

Если это фиксированный символ

sub(".*_(\\w+)\\.rds", "\\1", basename(mystring))

Или использовать gsub

gsub(".*_|\\.[^.]+$", "", mystring)
#[1] "cat"    "master"
...