在最后出现的字符和固定表达式之间提取字符串

时间:2019-03-20 11:45:40

标签: r regex stringr

我有一组字符串,例如

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 个答案:

答案 0 :(得分:2)

[^_]+$(?=\.rds)模式在字符串末尾匹配除_以外的1+个字符,然后它在字符串末尾后要求.rds ,这是不可能的,此正则表达式将永远不会匹配任何字符串。 (?<=[_]).+$(?=\.rds)在这方面是相似的,它不会匹配任何字符串,它会在找到第一个_后才开始匹配,并且会在尝试找到.rds之后的字符串的末尾它。

您可以使用

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

或者,等于R的基数:

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

请参见regex demo

模式详细信息

  • [^_]+-除_之外的1个或多个字符
  • (?=\.rds$)-正向超前,需要.rds在当前位置右侧紧邻字符串的末尾。

请参见Regulex graph

enter image description here

答案 1 :(得分:1)

使用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"