R: как заставить grep вернуть совпадение, а не всю строку - PullRequest
50 голосов
/ 03 июня 2010

У меня есть, наверное, действительно глупый grep в вопросе R. Извиняюсь, потому что кажется, что это должно быть так просто - я явно что-то упускаю.

У меня есть вектор строк, назовем его alice. Некоторые из alice напечатаны ниже:

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

Я бы хотел, чтобы grep дал мне номер после D, который появляется в некоторых из этих строк, условно для строки, содержащей "LIS" и пустой строки, или что-то иное.

Я надеялся, что grep вернет мне значение группы захвата, а не всю строку. Вот мое R-приправленное регулярное выражение:

pattern <- (?<=\\.D)([0-9]+)(?=.LIS)

ничего сложного. Но чтобы получить то, что мне нужно, вместо того, чтобы просто использовать grep(pattern, alice, value = TRUE, perl = TRUE), я делаю следующее, что кажется плохим:

reg.out <- regexpr(
    "(?<=\\.D)[0-9]+(?=.LIS)",
    alice,
    perl=TRUE
)
substr(alice,reg.out,reg.out + attr(reg.out,"match.length")-1)

Глядя на это сейчас, это не кажется слишком уродливым, но количество беспорядка, связанного с тем, чтобы заставить работать эту совершенно тривиальную вещь, было неловким. У кого-нибудь есть указания о том, как это сделать правильно?

Бонусные отметки за указание мне на веб-страницу, которая объясняет разницу между тем, к чему я обращаюсь с $, @ и attr.

Ответы [ 2 ]

53 голосов
/ 04 июня 2010

Попробуйте пакет stringr:

library(stringr)
str_match(alice, ".*\\.D([0-9]+)\\.LIS.*")[, 2]
37 голосов
/ 04 июня 2010

Вы можете сделать что-то вроде этого:

pat <- ".*\\.D([0-9]+)\\.LIS.*"
sub(pat, "\\1", alice)

Если вы хотите только подмножество alice, где ваш шаблон соответствует, попробуйте это:

pat <- ".*\\.D([0-9]+)\\.LIS.*"
sub(pat, "\\1", alice[grepl(pat, alice)])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...