J'ai ce qui est probablement un grep
vraiment stupide en question R. Toutes mes excuses, car cela semble être si facile - il me manque évidemment quelque chose.
J'ai un vecteur de chaînes, appelons-le alice
. Une partie de alice
est imprimée ci-dessous:
T.8EFF.SP.OT1.D5.VSVOVA#4
T.8EFF.SP.OT1.D6.LISOVA#1
T.8EFF.SP.OT1.D6.LISOVA#2
T.8EFF.SP.OT1.D6.LISOVA#3
T.8EFF.SP.OT1.D6.VSVOVA#4
T.8EFF.SP.OT1.D8.VSVOVA#3
T.8EFF.SP.OT1.D8.VSVOVA#4
T.8MEM.SP#1
T.8MEM.SP#3
T.8MEM.SP.OT1.D106.VSVOVA#2
T.8MEM.SP.OT1.D45.LISOVA#1
T.8MEM.SP.OT1.D45.LISOVA#3
J'aimerais que grep me donne le numéro après le D qui apparaît dans certaines de ces chaînes, conditionnel à la chaîne contenant "LIS" et une chaîne vide ou quelque chose d'autre.
J'espérais que grep me rendrait la valeur d'un groupe de capture plutôt que la chaîne entière. Voici mon expression rationnelle à saveur R:
pattern <- (?<=\\.D)([0-9]+)(?=.LIS)
rien de trop compliqué. Mais afin d'obtenir ce que je recherche, plutôt que d'utiliser simplement grep(pattern, alice, value = TRUE, Perl = TRUE)
je fais ce qui suit, ce qui semble mauvais:
reg.out <- regexpr(
"(?<=\\.D)[0-9]+(?=.LIS)",
alice,
Perl=TRUE
)
substr(alice,reg.out,reg.out + attr(reg.out,"match.length")-1)
En le regardant maintenant, cela ne semble pas trop moche, mais la quantité de dégâts qu'il a fallu pour faire fonctionner cette chose tout à fait triviale a été embarrassante. Quelqu'un a des conseils sur la façon de procéder correctement?
Points bonus pour m'avoir dirigé vers une page Web qui explique la différence entre tout ce que j'accède avec $
, @
Et attr
.
Vous pouvez faire quelque chose comme ça:
pat <- ".*\\.D([0-9]+)\\.LIS.*"
sub(pat, "\\1", alice)
Si vous voulez uniquement le sous-ensemble de alice
où votre modèle correspond, essayez ceci:
pat <- ".*\\.D([0-9]+)\\.LIS.*"
sub(pat, "\\1", alice[grepl(pat, alice)])
Essayez le package stringr:
library(stringr)
str_match(alice, ".*\\.D([0-9]+)\\.LIS.*")[, 2]