Use Regular expressions extract specific characters

Viewed 52
text <- c('d__Viruses|f__Closteroviridae|g__Closterovirus|s__Citrus_tristeza_virus',
'd__Viruses|o__Tymovirales|f__Alphaflexiviridae|g__Mandarivirus|s__Citrus_yellow_vein_clearing_virus',
'd__Viruses|o__Ortervirales|f__Retroviridae|s__Columba_palumbus_retrovirus')

I have tried but failed:

str_extract(text, pattern = 'f.*\\|') 

How can I get

f__Closteroviridae

f__Alphaflexiviridae

f__Retroviridae

Any help will be high appreciated!

2 Answers

Make the regex non-greedy and since you don't want "|" in final output use positive lookahead.

stringr::str_extract(text, 'f.*?(?=\\|)') 
#[1] "f__Closteroviridae"   "f__Alphaflexiviridae" "f__Retroviridae"   

In base R, we can use sub :

sub('.*(f_.*?)\\|.*', '\\1', text)
#[1] "f__Closteroviridae"   "f__Alphaflexiviridae" "f__Retroviridae" 

For a base R solution, I would use regmatches along with gregexpr:

m <- gregexpr("\\bf__[^|]+", text)
as.character(regmatches(text, m))

[1] "f__Closteroviridae"   "f__Alphaflexiviridae" "f__Retroviridae"

The advantage of using gregexpr as above is that should an input contain more than one f__ matching term, we could also capture it. For example:

x <- 'd__Viruses|f__Closteroviridae|g__Closterovirus|f__some_virus'
m <- gregexpr("\\bf__[^|]+", x)
regmatches(x, m)[[1]]

[1] "f__Closteroviridae" "f__some_virus" 

Data:

text <- c('d__Viruses|f__Closteroviridae|g__Closterovirus|s__Citrus_tristeza_virus',
          'd__Viruses|o__Tymovirales|f__Alphaflexiviridae|g__Mandarivirus|s__Citrus_yellow_vein_clearing_virus',
          'd__Viruses|o__Ortervirales|f__Retroviridae|s__Columba_palumbus_retrovirus')
Related