Выбирать группы захвата группы из регулярных выражений? (или: где gregexec?)

Учитывая регулярное выражение, содержащее группы захвата (круглые скобки) и строку, как я могу получить все подстроки, соответствующие группам захвата, подстроки, обычно ссылающиеся на "\ 1", "\ 2"?

Пример: рассмотрим цифры, которые будут содержать регулярные выражения, которым предшествует "xy":

s <- "xy1234wz98xy567"

r <- "xy(\\d+)"

Желаемый результат:

[1] "1234" "567" 

Первая попытка: gregexpr:

regmatches(s,gregexpr(r,s))
#[[1]]
#[1] "xy1234" "xy567" 

Не то, что я хочу, потому что он возвращает подстроки, соответствующие всему шаблону.

Вторая попытка: regexec:

regmatches(s,regexec("xy(\\d+)",s))
#[[1]]
#[1] "xy1234" "1234" 

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

Если существовала функция gregexec, расширение regexec в качестве gregexpr продолжается regexpr, моя проблема будет решена.

Итак, возникает вопрос: как получить все подстроки (или индексы, которые можно передать в regmatches, как в приведенных выше примерах), сопоставляя группы захвата в произвольном регулярном выражении?

Примечание: шаблон для r, приведенный выше, является просто глупым примером, он должен оставаться произвольным.

Ответ 1

Не знаю, как это сделать в базе, но вот пакет для ваших нужд:

library(stringr)

str_match_all(s, r)
#[[1]]
#     [,1]     [,2]  
#[1,] "xy1234" "1234"
#[2,] "xy567"  "567" 

Многие функции stringr также имеют параллели в базе R, поэтому вы также можете достичь этого, не используя stringr.

Например, здесь упрощенная версия того, как это работает, используя базу R:

sapply(regmatches(s,gregexpr(r,s))[[1]], function(m) regmatches(m,regexec(r,m)))

Ответ 2

Для базового решения R, как насчет использования gsub() для завершения обработки строк, извлеченных gregexpr() и regmatches()?

s <- "xy1234wz98xy567"
r <- "xy(\\d+)"

gsub(r, "\\1", regmatches(s,gregexpr(r,s))[[1]])
# [1] "1234" "567" 

Ответ 3

strapplyc в пакете gsubfn делает следующее:

> library(gsubfn)
>
> strapplyc(s, r)
[[1]]
[1] "1234" "567" 

Попробуйте ?strapplyc для получения дополнительной информации и примеров.

Связанные функции

1) Обобщение strapplyc равно strapply в том же пакете. Он принимает функцию, которая вводит захваченные части каждого совпадения и возвращает выход функции. Когда функция c, она сводится к strapplyc. Например, предположим, что мы хотим вернуть результаты как числовые:

> strapply(s, r, as.numeric)
[[1]]
[1] 1234  567

2) gsubfn - это еще одна связанная функция в одном пакете. Это похоже на gsub, за исключением того, что строка замены может быть заменой (или списком замещения или заменяющим прото-объектом). Функция замены вводит захваченные части и выводит замену. Замена заменяет совпадение во входной строке. Если используется формула, как в этом примере, правая часть формулы рассматривается как тело функции. В этом примере мы заменим совпадение на XY{#}, где # в два раза соответствует номеру ввода.

> gsubfn(r, ~ paste0("XY{", 2 * as.numeric(x), "}"), s)
[1] "XY{2468}wz98XY{1134}"

UPDATE: Добавлены примеры strapply и gsubfn.