在短语之前拉出文本 - Regex R
Pull out text before phrase - Regex R
我希望在 R
中使用 Regex 提取出现在一组短语之前的文本。
示例短语 c("PHRASE1", "PHRASE2", "PHRASE3")
。
示例文本:
*NAME ALPHA PHRASE1 BLA BLA TEXT 81249
*NAME BETA PHRASE1 BLA BLA 81229
*NAME GAMMA PHRASE2 BLA BLA TEXT 85129
*NAME DELTA PHRASE3 BLA BLA 86129
*NAME EPSILON PHRASE2 BLA BLA 81729
我想拉出下面的c("NAME ALPHA", "NAME BETA", "NAME GAMMA")
等等(忽略*
)。
正则表达式 101 link: https://regex101.com/r/Fzinr8/1
初次尝试
(!\*)q+(?=PHRASE1)
在R
中:
str_extract(x, "(!\*)q+(?=PHRASE1)")
一个stringr
解决方案
您可以使用
x<-c("*NAME ALPHA PHRASE1 BLA BLA TEXT 81249","*NAME BETA PHRASE1 BLA BLA 81229","*NAME GAMMA PHRASE2 BLA BLA TEXT 85129","*NAME DELTA PHRASE3 BLA BLA 86129","*NAME EPSILON PHRASE2 BLA BLA 81729")
library(stringr)
context <- c("PHRASE1", "PHRASE2", "PHRASE3")
str_match(x, paste0("\*(.*?)\s+(?:", paste(context, collapse="|"), ")"))[,2]
# => [1] "NAME ALPHA" "NAME BETA" "NAME GAMMA" "NAME DELTA" "NAME EPSILON"
参见regex demo。
详情
\*
- 一个 *
字符
(.*?)
- 第 1 组(在 str_match
之后使用 [,2]
访问):除换行字符外的任何零个或多个字符尽可能少
\s+(?:PHRASE1|PHRASE2|PHRASE3)
- 1 个或多个空格和上下文字符串之一。
基础 R 解决方案:
x<-c("*NAME ALPHA PHRASE1 BLA BLA TEXT 81249","*NAME BETA PHRASE1 BLA BLA 81229","*NAME GAMMA PHRASE2 BLA BLA TEXT 85129","*NAME DELTA PHRASE3 BLA BLA 86129","*NAME EPSILON PHRASE2 BLA BLA 81729")
context <- c("PHRASE1", "PHRASE2", "PHRASE3")
pattern <- paste0("\*\K.*?(?=\s+(?:", paste(context, collapse="|"), "))")
regmatches(x, regexpr(pattern, x, perl=TRUE))
## => [1] "NAME ALPHA" "NAME BETA" "NAME GAMMA" "NAME DELTA" "NAME EPSILON"
见R demo online。请注意,此方法需要 PCRE 正则表达式才能工作,因此 perl=TRUE
参数是必需的。
\K
PCRE 构造忽略了当前匹配内存缓冲区中到目前为止匹配的文本。 (?=...)
构造是一个积极的前瞻性匹配字符串中的位置(这就是为什么它被称为零宽度断言),紧随其后的是前瞻性模式。
正在将我的评论转换为答案,以便未来的访问者可以轻松找到解决方案。
您可以通过后视和前视来使用此正则表达式:
str_extract(x, '(?<=\*).*?(?=\s(?:PHRASE1|PHRASE2|PHRASE3))');
正则表达式详细信息:
(?<=\*)
:断言我们在之前的位置有一个*
.*?
:匹配0个或多个任意字符(惰性匹配)
(?=\s(?:PHRASE1|PHRASE2|PHRASE3))
:正面前瞻断言我们在当前位置 之前有一个空格后跟(?:PHRASE1|PHRASE2|PHRASE3)
替代 strsplit()
然后删除尾随空格
代码
sapply(str2, function(z){
# remove * and whitespaces
gsub("[*]|\s+$", "",
# split by phrase and choose part of interest
sapply(strsplit(str1, z)[grepl(z, str1)], "[[", 1))
})
# $PHRASE1
# [1] "NAME ALPHA" "NAME BETA"
# $PHRASE2
# [1] "NAME GAMMA" "NAME EPSILON"
# $PHRASE3
# [1] "NAME DELTA"
数据
str1 <- c("*NAME ALPHA PHRASE1 BLA BLA TEXT 81249",
"*NAME BETA PHRASE1 BLA BLA 81229",
"*NAME GAMMA PHRASE2 BLA BLA TEXT 85129",
"*NAME DELTA PHRASE3 BLA BLA 86129",
"*NAME EPSILON PHRASE2 BLA BLA 81729")
str2 <- c("PHRASE1", "PHRASE2", "PHRASE3")
我希望在 R
中使用 Regex 提取出现在一组短语之前的文本。
示例短语 c("PHRASE1", "PHRASE2", "PHRASE3")
。
示例文本:
*NAME ALPHA PHRASE1 BLA BLA TEXT 81249
*NAME BETA PHRASE1 BLA BLA 81229
*NAME GAMMA PHRASE2 BLA BLA TEXT 85129
*NAME DELTA PHRASE3 BLA BLA 86129
*NAME EPSILON PHRASE2 BLA BLA 81729
我想拉出下面的c("NAME ALPHA", "NAME BETA", "NAME GAMMA")
等等(忽略*
)。
正则表达式 101 link: https://regex101.com/r/Fzinr8/1
初次尝试
(!\*)q+(?=PHRASE1)
在R
中:
str_extract(x, "(!\*)q+(?=PHRASE1)")
一个stringr
解决方案
您可以使用
x<-c("*NAME ALPHA PHRASE1 BLA BLA TEXT 81249","*NAME BETA PHRASE1 BLA BLA 81229","*NAME GAMMA PHRASE2 BLA BLA TEXT 85129","*NAME DELTA PHRASE3 BLA BLA 86129","*NAME EPSILON PHRASE2 BLA BLA 81729")
library(stringr)
context <- c("PHRASE1", "PHRASE2", "PHRASE3")
str_match(x, paste0("\*(.*?)\s+(?:", paste(context, collapse="|"), ")"))[,2]
# => [1] "NAME ALPHA" "NAME BETA" "NAME GAMMA" "NAME DELTA" "NAME EPSILON"
参见regex demo。
详情
\*
- 一个*
字符(.*?)
- 第 1 组(在str_match
之后使用[,2]
访问):除换行字符外的任何零个或多个字符尽可能少\s+(?:PHRASE1|PHRASE2|PHRASE3)
- 1 个或多个空格和上下文字符串之一。
基础 R 解决方案:
x<-c("*NAME ALPHA PHRASE1 BLA BLA TEXT 81249","*NAME BETA PHRASE1 BLA BLA 81229","*NAME GAMMA PHRASE2 BLA BLA TEXT 85129","*NAME DELTA PHRASE3 BLA BLA 86129","*NAME EPSILON PHRASE2 BLA BLA 81729")
context <- c("PHRASE1", "PHRASE2", "PHRASE3")
pattern <- paste0("\*\K.*?(?=\s+(?:", paste(context, collapse="|"), "))")
regmatches(x, regexpr(pattern, x, perl=TRUE))
## => [1] "NAME ALPHA" "NAME BETA" "NAME GAMMA" "NAME DELTA" "NAME EPSILON"
见R demo online。请注意,此方法需要 PCRE 正则表达式才能工作,因此 perl=TRUE
参数是必需的。
\K
PCRE 构造忽略了当前匹配内存缓冲区中到目前为止匹配的文本。 (?=...)
构造是一个积极的前瞻性匹配字符串中的位置(这就是为什么它被称为零宽度断言),紧随其后的是前瞻性模式。
正在将我的评论转换为答案,以便未来的访问者可以轻松找到解决方案。
您可以通过后视和前视来使用此正则表达式:
str_extract(x, '(?<=\*).*?(?=\s(?:PHRASE1|PHRASE2|PHRASE3))');
正则表达式详细信息:
(?<=\*)
:断言我们在之前的位置有一个*
.*?
:匹配0个或多个任意字符(惰性匹配)(?=\s(?:PHRASE1|PHRASE2|PHRASE3))
:正面前瞻断言我们在当前位置 之前有一个空格后跟
(?:PHRASE1|PHRASE2|PHRASE3)
替代 strsplit()
然后删除尾随空格
代码
sapply(str2, function(z){
# remove * and whitespaces
gsub("[*]|\s+$", "",
# split by phrase and choose part of interest
sapply(strsplit(str1, z)[grepl(z, str1)], "[[", 1))
})
# $PHRASE1
# [1] "NAME ALPHA" "NAME BETA"
# $PHRASE2
# [1] "NAME GAMMA" "NAME EPSILON"
# $PHRASE3
# [1] "NAME DELTA"
数据
str1 <- c("*NAME ALPHA PHRASE1 BLA BLA TEXT 81249",
"*NAME BETA PHRASE1 BLA BLA 81229",
"*NAME GAMMA PHRASE2 BLA BLA TEXT 85129",
"*NAME DELTA PHRASE3 BLA BLA 86129",
"*NAME EPSILON PHRASE2 BLA BLA 81729")
str2 <- c("PHRASE1", "PHRASE2", "PHRASE3")