Как я могу использовать обратные ссылки с `grep` в R?

Я ищу элегантный способ возврата ссылок с использованием регулярных выражений в R. Le me объясните:

Скажем, я хочу найти строки, начинающиеся с имени месяца:

x <- c("May, 1, 2011", "30 June 2011")
grep("May|^June", x, value=TRUE)
[1] "May, 1, 2011"

Это работает, но я действительно хочу выделить месяц (т.е. "май", а не всю строку со строкой.

Таким образом, можно использовать gsub, чтобы вернуть обратную ссылку, используя параметр substitute. Но это имеет две проблемы:

  • Вы должны обернуть шаблон внутри ". * (pattern). *)", чтобы замена выполнялась по всей строке.
  • Вместо возврата NA для несогласованных строк gsub возвращает исходную строку. Это явно не то, что я хочу:

Код и результаты:

gsub(".*(^May|^June).*", "\\1", x) 
[1] "May"          "30 June 2011"

Я мог бы, вероятно, написать обходное решение, выполнив всевозможные дополнительные проверки, но это быстро становится очень грязным.

Чтобы быть кристально чистым, желаемые результаты должны быть:

[1] "May"          NA

Есть ли простой способ достичь этого?

Ответы

Ответ 1

Пакет 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.

Ответ 2

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"

Ответ 3

Пакет gsubfn более общий, чем функции grep и regexpr, и у вас есть способы вернуть backrefrences, см. функцию привязки.