提取 R 中其他两个字符串之间的字符串

我试图找到一种简单的方法来提取出现在两个已知子字符串之间的未知子字符串(可以是任何内容)。例如,我有一个字符串:

a<-" anything goes here, STR1 GET_ME STR2, anything goes here"

我需要提取字符串 GET_ME,它位于 STR1和 STR2之间(没有空格)。

我正在尝试 str_extract(a, "STR1 (.+) STR2"),但我得到了整个比赛

[1] "STR1 GET_ME STR2"

当然,我可以去掉已知的字符串,来隔离我需要的子字符串,但是我认为应该有一种更简洁的方法来做到这一点,即使用正确的正则表达式。

94113 次浏览

您可以使用 str_matchSTR1 (.*?) STR2(注意,空格是“有意义的”,如果您想只匹配 STR1STR2之间的任何使用 STR1(.*?)STR2,或使用 STR1\\s*(.*?)\\s*STR2修剪您需要的值)。如果有多个事件,请使用 str_match_all

此外,如果您需要匹配跨越换行符/换行符的字符串,请在模式的开头添加 (?s): (?s)STR1(.*?)STR2/(?s)STR1\\s*(.*?)\\s*STR2

library(stringr)
a <- " anything goes here, STR1 GET_ME STR2, anything goes here"
res <- str_match(a, "STR1\\s*(.*?)\\s*STR2")
res[,2]
[1] "GET_ME"

另一种使用基本 R regexec的方法(获得第一个匹配) :

test <- " anything goes here, STR1 GET_ME STR2, anything goes here STR1 GET_ME2 STR2"
pattern <- "STR1\\s*(.*?)\\s*STR2"
result <- regmatches(test, regexec(pattern, test))
result[[1]][2]
[1] "GET_ME"

这是另一种使用基数 R 的方法

a<-" anything goes here, STR1 GET_ME STR2, anything goes here"


gsub(".*STR1 (.+) STR2.*", "\\1", a)

产出:

[1] "GET_ME"

另一种选择是使用 qdapRegex::ex_between提取左右边界之间的字符串

qdapRegex::ex_between(a, "STR1", "STR2")[[1]]
#[1] "GET_ME"

它还可以处理多个事件

a <- "anything STR1 GET_ME STR2, anything goes here, STR1 again get me STR2"


qdapRegex::ex_between(a, "STR1", "STR2")[[1]]
#[1] "GET_ME"       "again get me"

或者多个左右边界

a <- "anything STR1 GET_ME STR2, anything goes here, STR4 again get me STR5"
qdapRegex::ex_between(a, c("STR1", "STR4"), c("STR2", "STR5"))[[1]]
#[1] "GET_ME"       "again get me"

第一次捕获在“ STR1”和“ STR2”之间,第二次捕获在“ STR4”和“ STR5”之间。

我们可以使用 { un货},在这种情况下,我们根本不需要 regex:

library(unglue)
unglue::unglue_vec(
" anything goes here, STR1 GET_ME STR2, anything goes here",
"{}STR1 {x} STR2{}")
#> [1] "GET_ME"

{}匹配任何东西而不保留它,{x}捕获它的匹配(除 x以外的任何变量都可以使用。Syntax"{}STR1 {x} STR2{}"是: "{=.*?}STR1 {x=.*?} STR2{=.*?}"的简称

如果你也想提取边角料,你可以这样做:

unglue::unglue_data(
" anything goes here, STR1 GET_ME STR2, anything goes here",
"{left}, STR1 {x} STR2, {right}")
#>                  left      x              right
#> 1  anything goes here GET_ME anything goes here