查找与字符串中的模式匹配的嵌套子字符串

时间:2019-03-23 13:37:47

标签: r regex

我需要找到该字符串'DGHDAGRTDRPDRMGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY*AVR*GQRRDVTTEFIHLLRCLDLSSFACMCAPARH*SRSLLIYSPKRLRNIASHRSYGIVCTSG*CTWINV*QIS*FATH*SKCIAPNLSHADKPRSLVLTPTTLRFSKPAYRRPLIREAMDLWIRASICWGMGLLN*KDWP*ESGYAYYVCELESGLRLMNPDARGFSRV*HVCSSA*LTWPSPFPEQAFLLRFTEPRHKLLYV*D*VNACLVRSSASASIM'中以字符M开头并以字符*结尾的子字符串 all

我尝试使用str_extract_all()stri_extract_all(),但无法获得想要的结果:

aa <- 'DGHDAGRTDRPDRMGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY*AVR*GQRRDVTTEFIHLLRCLDLSSFACMCAPARH*SRSLLIYSPKRLRNIASHRSYGIVCTSG*CTWINV*QIS*FATH*SKCIAPNLSHADKPRSLVLTPTTLRFSKPAYRRPLIREAMDLWIRASICWGMGLLN*KDWP*ESGYAYYVCELESGLRLMNPDARGFSRV*HVCSSA*LTWPSPFPEQAFLLRFTEPRHKLLYV*D*VNACLVRSSASASIM'

str_extract_all(aa, 'M.*\\*')[[1]]
[1] "MGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY*AVR*GQRRDVTTEFIHLLRCLDLSSFACMCAPARH*SRSLLIYSPKRLRNIASHRSYGIVCTSG*CTWINV*QIS*FATH*SKCIAPNLSHADKPRSLVLTPTTLRFSKPAYRRPLIREAMDLWIRASICWGMGLLN*KDWP*ESGYAYYVCELESGLRLMNPDARGFSRV*HVCSSA*LTWPSPFPEQAFLLRFTEPRHKLLYV*D*"

stri_extract_all(aa, regex = ('M.*/*'))[[1]]
[1] "MGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY*AVR*GQRRDVTTEFIHLLRCLDLSSFACMCAPARH*SRSLLIYSPKRLRNIASHRSYGIVCTSG*CTWINV*QIS*FATH*SKCIAPNLSHADKPRSLVLTPTTLRFSKPAYRRPLIREAMDLWIRASICWGMGLLN*KDWP*ESGYAYYVCELESGLRLMNPDARGFSRV*HVCSSA*LTWPSPFPEQAFLLRFTEPRHKLLYV*D*VNACLVRSSASASIM"

但是我得到了一个子字符串,该子字符串以第一个M开始,并以最后一个*或最后一个字符aa结尾。我想得到的是所有子字符串,即使一个子字符串嵌套在另一个子字符串中也是如此:

MDDDVLPLISLFWTFGRGDVPRRY*
MCAPARH*
MDLWIRASICWGMGLLN*
MGLLN*
MNPDARGFSRV*

以下是有关我的软件版本的信息:

  • Windows 10
  • R版本3.5.2
  • R studio版本1.1.463
  • stringr版本1.4.0

对不起,如果我使用了错误的术语,我还是编程新手。

谢谢您的帮助!

3 个答案:

答案 0 :(得分:3)

需要找到所有嵌套的子字符串,这表明递归可能是最简单的方法:

首先删除最后一个*之后的所有内容(因为根据问题,我们搜索的字符串必须以最后一个*分隔)。

x = sub("*[^*]+$", "", aa) 

现在让我们在每个*

进行拆分
y = unlist(strsplit(x, '*', fixed = T))

并仅保留至少包含一个M的字符串

y = grep('M', y, value = T)

现在我们使用递归函数来获取所有子字符串

find.M = function(z){
  z = sub('.+?M', 'M', z)
  if (length(zz <- grep('.+M', z, value = T))) {
    c(z, find.M(sub('.+?M','M',zz)))
  }
  else z
}

find.M(y)
# [1] "MGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY"
# [2] "MCAPARH"                                                     
# [3] "MDLWIRASICWGMGLLN"                                           
# [4] "MNPDARGFSRV"                                                 
# [5] "MDDDVLPLISLFWTFGRGDVPRRY"                                    
# [6] "MGLLN" 

答案 1 :(得分:1)

编辑:这并不能完全产生所需的输出,但我想与他人共享(因为我也花了一些时间):

library(stringi)
result<-unlist(strsplit(aa,".(?=M.*)",perl = TRUE))
res<-unlist(stri_split(unlist(result),regex="[A-Z](?<=\\*[A-Z]|(?<=\\M[A-Z]))"))
res1<-res[grep("^M",unlist(res))]
res1[stri_endswith(res1,charclass = "[*|W]")]
#[1] "MDDDVLPLISLFWTFGRGDVPRRY*" "MCAPARH*"                  "MDLWIRASICW"              
#[4] "MGLLN*"                    "MNPDARGFSRV*"

原始

我们可以使用(这已删除了* ):

aa<-'DGHDAGRTDRPDRMGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY*AVR*GQRRDVTTEFIHLLRCLDLSSFACMCAPARH*SRSLLIYSPKRLRNIASHRSYGIVCTSG*CTWINV*QIS*FATH*SKCIAPNLSHADKPRSLVLTPTTLRFSKPAYRRPLIREAMDLWIRASICWGMGLLN*KDWP*ESGYAYYVCELESGLRLMNPDARGFSRV*HVCSSA*LTWPSPFPEQAFLLRFTEPRHKLLYV*D*VNACLVRSSASASIM'
aa
res1<-unlist(strsplit(aa,".(?=M)",perl = TRUE))
res2<-unlist(strsplit(res1[grep("\\*{1,}",res1)],"\\*"))
res2[grep("^M",res2)]

结果:

   # [1] "MDDDVLPLISLFWTFGRGDVPRRY" "MCAPARH"                  "MGLLN"                   
   # [4] "MNPDARGFSRV" 

答案 2 :(得分:1)

您可以使用[^\\*]*来匹配星号以外的任何内容。注意,您需要所有匹配项,包括任何重叠的模式,我们可以添加前瞻性。 stringr似乎不支持此功能,但stringi::stri_match_all_regex()可以使用此功能:

library(stringi)

stri_match_all_regex(aa, '(?=(M[^\\*]*\\*))')[[1]][,2]

# [1] "MGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY*"
# [2] "MDDDVLPLISLFWTFGRGDVPRRY*"                                    
# [3] "MCAPARH*"                                                     
# [4] "MDLWIRASICWGMGLLN*"                                           
# [5] "MGLLN*"                                                       
# [6] "MNPDARGFSRV*"