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

Regex 在R中的其他两个字符串之间提取字符串,regex,r,stringr,Regex,R,Stringr,我试图找到一种简单的方法来提取出现在两个已知子字符串之间的未知子字符串(可以是任何东西)。例如,我有一个字符串: a您可以使用str\u match与STR1(.*STR2)匹配(注意,如果您只想匹配STR1和STR2之间的任何内容,则空格是“有意义的”,可以使用STR1(.*STR2),或者使用STR1\\s*(.*s*STR2来修剪所需的值)。如果多次出现,请使用str\u match\u all 另外,如果需要匹配跨换行符/换行符的字符串,请在模式的开头添加(?s):(?s)STR1(.*

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


a您可以使用
str\u match
STR1(.*STR2
)匹配(注意,如果您只想匹配
STR1
STR2
之间的任何内容,则空格是“有意义的”,可以使用
STR1(.*STR2
),或者使用
STR1\\s*(.*s*STR2
来修剪所需的值)。如果多次出现,请使用
str\u match\u 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"

这里有另一种使用base R的方法

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

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

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

qdapRegex::ex_between(a, "STR1", "STR2")[[1]]
#[1] "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"
它也适用于多个引用

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我们可以使用{unglue},在这种情况下,我们根本不需要正则表达式:

library(unglue)
unglue::unglue_vec(
  " anything goes here, STR1 GET_ME STR2, anything goes here", 
  "{}STR1 {x} STR2{}")
#> [1] "GET_ME"
{}
匹配任何内容而不保留它,
{x}
捕获其匹配项(可以使用
x
以外的任何变量。语法可以是:
“{=.*.}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

有效!问号的作用是什么?没有问号也有效。
这里是懒惰(非贪婪)的一部分量词。它匹配尽可能少的字符,而
*
将匹配尽可能多的字符。因此,
STR1.*?STR2
regex匹配
STR1 xx STR2
,而
STR1.*.STR2
将匹配
STR1 xx STR2 zzz STR2
。如果您希望输入中有多个匹配项,则必须使用惰性量词。另外,仅供参考:如果
STR1
STR2
之间的字符串部分可能包含换行符,您需要在模式前面加上
(-s)
“(-s)STR1(.*STR2)”
@Wiktor:你能解释一下为什么str\u match
输出是在一个矩阵中吗?这似乎很不方便,特别是当大多数人想要的唯一输出是
[,2]
@Nettle时,我不同意,因为如果任何人只想要
[,2]
,他们应该只使用
regmatches(a,regexpr(“STR1\\s*\\K.*(?=\\s*STR2)”使用
stringr
,也可以使用类似
str_-extract_-all(a,“(?)s”(?@Wiktor:
regmatches/regexpr
combo)的模式在stringr中很好的表达式上阻塞…所以您的表达式
str-extract_-all(a,“(?)使用奇妙的函数
regcapturedmatches(test,gregexpr('STR1+))STR2',test,perl=TRUE)
中没有实际的正确答案,我必须重新打开这个问题。如果这篇文章应该与那篇文章一起迁移,请让版主知道。如果我们想使用任何变量来代替STR1和STR2,我们该怎么做。假设我将STR1分配给a,将STR2分配给b,现在我们如何使用正则表达式来提取a和bin之间的字符串,而不是
”{left},STR1{x}STR2,{right}
您可以使用
sprintf({left},%s{x}%s,{right}),a,b)
paste0({left},,,a,{x},b,,{right}”)
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"
library(unglue)
unglue::unglue_vec(
  " anything goes here, STR1 GET_ME STR2, anything goes here", 
  "{}STR1 {x} STR2{}")
#> [1] "GET_ME"
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