从正则表达式中提取捕获组匹配? (或者:gregexec在哪里?)

时间:2013-09-04 17:48:30

标签: regex r backreference

给定包含capture groups(括号)和字符串的正则表达式,如何获得所有与捕获组匹配的子字符串,即通常由“\ 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模式只是一个愚蠢的例子,它必须保持随意。

3 个答案:

答案 0 :(得分:12)

对于基本R解决方案,如何使用gsub()来完成处理由gregexpr()regmatches()提取的字符串?

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

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

答案 1 :(得分:11)

不确定在基地做这件事,但这里有一个满足您需求的套餐:

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 :(得分:8)

gsubfn package中的

strapplyc执行此操作:

> 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,但替换字符串可以是替换函数(或替换列表或替换proto对象)。替换功能输入捕获的部分并输出替换。替换将替换输入字符串中的匹配项。如果使用公式,如在该示例中,公式的右侧被视为函数体。在此示例中,我们将匹配替换为XY{#},其中#是匹配输入数的两倍。

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

更新:添加了strapplygsubfn个例子。