Как я могу использовать обратные ссылки с "grep" в R?
Я ищу элегантный способ возврата ссылок с использованием регулярных выражений в R. Le me explain:
предположим, я хочу найти строки, которые начинаются с имени месяца:
x <- c("May, 1, 2011", "30 June 2011")
grep("May|^June", x, value=TRUE)
[1] "May, 1, 2011"
это работает, но я действительно хочу изолировать месяц (т. е. "май", а не всю согласованную строку.
Итак, можно использовать gsub
чтобы вернуть обратную ссылку, используя . Но у этого есть две проблемы:
- вы должны обернуть узор внутри ".*(узор.)* ) "таким образом, подстановка происходит по всей строке.
- вместо того, чтобы возвращать NA для несогласованных строк,
gsub
возвращает исходную строку. Это явно не то, чего я желаю:--16-->код и результаты:
gsub(".*(^May|^June).*", "1", x) [1] "May" "30 June 2011"
я мог бы, вероятно, кодировать обходной путь, выполняя все виды дополнительных проверок, но это быстро становится очень грязным.
должен быть кристально чистым, желаемые результаты должны быть:
[1] "May" NA
есть ли простой способ достичь этого?
3 ответов
на stringr
пакет имеет функцию именно для этого:
library(stringr)
x <- c("May, 1, 2011", "30 June 2011", "June 2012")
str_extract(x, "May|^June")
# [1] "May" NA "June"
Это довольно тонкая обертка вокруг regexpr
, а stringr
обычно упрощает обработку строк, будучи более последовательным, чем базовые функции R.
regexpr
похож на grep
, но возвращает позицию и длину (первого) соответствия в каждой строке:
> x <- c("May, 1, 2011", "30 June 2011", "June 2012")
> m <- regexpr("May|^June", x)
> m
[1] 1 -1 1
attr(,"match.length")
[1] 3 -1 4
это означает, что первая строка имела совпадение длины 3, глядя на позицию 1, вторая строка не имела совпадения, а третья строка имела совпадение длины 4 в позиции 1.
чтобы извлечь спички, вы можете использовать что-то вроде:
> m[m < 0] = NA
> substr(x, m, m + attr(m, "match.length") - 1)
[1] "May" NA "June"
пакет gsubfn является более общим, чем функции grep и regexpr, и имеет способы возврата backrefrences, см. функцию strapply.