#r #regex
#r #регулярное выражение
Вопрос:
Мне нужно найти все подстроки в этой строке, 'DGHDAGRTDRPDRMGIEGTRNELPVAYHYNRTLSSNAEPLVESYLTHVLMDDDVLPLISLFWTFGRGDVPRRY*AVR*GQRRDVTTEFIHLLRCLDLSSFACMCAPARH*SRSLLIYSPKRLRNIASHRSYGIVCTSG*CTWINV*QIS*FATH*SKCIAPNLSHADKPRSLVLTPTTLRFSKPAYRRPLIREAMDLWIRASICWGMGLLN*KDWP*ESGYAYYVCELESGLRLMNPDARGFSRV*HVCSSA*LTWPSPFPEQAFLLRFTEPRHKLLYV*D*VNACLVRSSASASIM'
которые начинаются с символа M
и заканчиваются символом *
.
Я пытался использовать 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
Извините, если я использовал неправильный жаргон, я все еще новичок в программировании.
Спасибо за всю вашу помощь!
Комментарии:
1. Не вижу ни одной, начинающейся с M, если вы просто не хотите их разделить.
2. Если мы рассмотрим это,
MDLWIRASICWGMGLLN*
только одна заканчивается на*
.
Ответ №1:
Необходимость поиска всех вложенных подстрок предполагает, что рекурсия может быть самым простым способом:
Сначала удалите все после final *
(поскольку строки, которые мы ищем, должны быть разделены final * в соответствии с вопросом).
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"
Ответ №2:
РЕДАКТИРОВАТЬ: это не совсем приводит к желаемому результату, но я подумал, что поделюсь им (поскольку я также потратил на это некоторое время):
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"
Комментарии:
1. Это не позволяет рекурсивно находить все вложенные подстроки
2. Верно, одна отсутствует.
Ответ №3:
Вы можете использовать [^\*]*
для сопоставления с чем угодно, кроме звездочки. Отметив, что вам нужны все совпадения, включая любые перекрывающиеся шаблоны, мы можем добавить предварительный просмотр. Похоже, это не поддерживается с 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*"