如何在 R 中提取这些多个正则表达式组
How can I extract these multiple regex groups in R
我有以下格式的字符串输入:
my.strings <- c("FACT11", "FACT11:FACT20", "FACT1sometext:FACT20", "FACT1text with spaces:FACT20", "FACT14:FACT20", "FACT1textAnd1312:FACT2etc", "FACT12:FACT22:FACT31")
我想提取所有 "FACT" 和 FACT 后面的第一个数字。所以这个例子的结果是:
c("FACT1", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2 FACT3")
或者,结果可以是一个列表,其中列表的每个元素都是一个向量,最多包含 1 个项目。
到目前为止我得到的是:
gsub("(FACT[1-3]).*?:(FACT[1-3]).*", '\1 \2', my.strings)
# [1] "FACT11" "FACT1 FACT2 " "FACT1 FACT2 " "FACT1 FACT2 " "FACT1 FACT2 " "FACT1 FACT2 "
# [7] "FACT1 FACT2 " "FACT1 FACT2 "
它看起来不错,除了第一个元素的 "FACT11" 而不是 "FACT1"(删除第二个“1”),并且缺少最后一个元素的 "FACT3" my.strings
个。但是将另一个组添加到 gsub
不知何故把整个事情搞砸了。
gsub("(FACT[1-3]).*?:(FACT[1-3]).*?:(FACT[1-3]).*?", '\1 \2 \3', my.strings)
# [1] "FACT11" "FACT11:FACT20" "FACT1sometext:FACT20"
# [4] "FACT1text with spaces:FACT20" "FACT14:FACT20" "FACT1textAnd1312:FACT2etc"
# [7] "FACT12:FACT21" "FACT1 FACT2 FACT31"
那么如何正确提取组?
一个选项是 str_extract_all
从 stringr
提取所有 'FACT' 子字符串,后跟一个可以是 1 到 3 ([1-3]
) 的数字到 list
共 vector
秒。然后,map
通过 list
元素和 paste
vector
到单个字符串
library(tidyverse)
str_extract_all(my.strings, "FACT[1-3]") %>%
map_chr(paste, collapse= ' ')
#[1] "FACT1" "FACT1 FACT2" "FACT1 FACT2"
#[4] "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2"
#[7] "FACT1 FACT2 FACT3"
或使用 base R
中的 gsub
gsub("\s{2,}", " ", trimws(gsub("(FACT[1-3])(*SKIP)(*FAIL)|.",
" ", my.strings, perl = TRUE)))
#[1] "FACT1" "FACT1 FACT2" "FACT1 FACT2"
#[4] "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2"
#[7] "FACT1 FACT2 FACT3"
您也可以使用基础 R 方法:
> m <- regmatches(my.strings, gregexpr("FACT[1-3]", my.strings))
> sapply(m, paste, collapse=" ")
[1] "FACT1"
[2] "FACT1 FACT2"
[3] "FACT1 FACT2"
[4] "FACT1 FACT2"
[5] "FACT1 FACT2"
[6] "FACT1 FACT2"
[7] "FACT1 FACT2 FACT3"
提取所有符合您的 FACT[1-3]
(或 FACT[0-9]
,或 FACT\d
)模式的匹配项,然后 "join" 使用 space。
另一种基础 R 替代方案:
此解决方案使用 FACT
以一位数字结尾的事实。
my.strings %>%
gsub("(\d)\d*", "\1:", ., perl = TRUE) %>%
strsplit(":") %>%
sapply(function(x) paste(x[grepl("FACT", x)], collapse = " "))
[1] "FACT1" "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2"
[5] "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2 FACT3"
我有以下格式的字符串输入:
my.strings <- c("FACT11", "FACT11:FACT20", "FACT1sometext:FACT20", "FACT1text with spaces:FACT20", "FACT14:FACT20", "FACT1textAnd1312:FACT2etc", "FACT12:FACT22:FACT31")
我想提取所有 "FACT" 和 FACT 后面的第一个数字。所以这个例子的结果是:
c("FACT1", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2 FACT3")
或者,结果可以是一个列表,其中列表的每个元素都是一个向量,最多包含 1 个项目。
到目前为止我得到的是:
gsub("(FACT[1-3]).*?:(FACT[1-3]).*", '\1 \2', my.strings)
# [1] "FACT11" "FACT1 FACT2 " "FACT1 FACT2 " "FACT1 FACT2 " "FACT1 FACT2 " "FACT1 FACT2 "
# [7] "FACT1 FACT2 " "FACT1 FACT2 "
它看起来不错,除了第一个元素的 "FACT11" 而不是 "FACT1"(删除第二个“1”),并且缺少最后一个元素的 "FACT3" my.strings
个。但是将另一个组添加到 gsub
不知何故把整个事情搞砸了。
gsub("(FACT[1-3]).*?:(FACT[1-3]).*?:(FACT[1-3]).*?", '\1 \2 \3', my.strings)
# [1] "FACT11" "FACT11:FACT20" "FACT1sometext:FACT20"
# [4] "FACT1text with spaces:FACT20" "FACT14:FACT20" "FACT1textAnd1312:FACT2etc"
# [7] "FACT12:FACT21" "FACT1 FACT2 FACT31"
那么如何正确提取组?
一个选项是 str_extract_all
从 stringr
提取所有 'FACT' 子字符串,后跟一个可以是 1 到 3 ([1-3]
) 的数字到 list
共 vector
秒。然后,map
通过 list
元素和 paste
vector
到单个字符串
library(tidyverse)
str_extract_all(my.strings, "FACT[1-3]") %>%
map_chr(paste, collapse= ' ')
#[1] "FACT1" "FACT1 FACT2" "FACT1 FACT2"
#[4] "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2"
#[7] "FACT1 FACT2 FACT3"
或使用 base R
gsub
gsub("\s{2,}", " ", trimws(gsub("(FACT[1-3])(*SKIP)(*FAIL)|.",
" ", my.strings, perl = TRUE)))
#[1] "FACT1" "FACT1 FACT2" "FACT1 FACT2"
#[4] "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2"
#[7] "FACT1 FACT2 FACT3"
您也可以使用基础 R 方法:
> m <- regmatches(my.strings, gregexpr("FACT[1-3]", my.strings))
> sapply(m, paste, collapse=" ")
[1] "FACT1"
[2] "FACT1 FACT2"
[3] "FACT1 FACT2"
[4] "FACT1 FACT2"
[5] "FACT1 FACT2"
[6] "FACT1 FACT2"
[7] "FACT1 FACT2 FACT3"
提取所有符合您的 FACT[1-3]
(或 FACT[0-9]
,或 FACT\d
)模式的匹配项,然后 "join" 使用 space。
另一种基础 R 替代方案:
此解决方案使用 FACT
以一位数字结尾的事实。
my.strings %>%
gsub("(\d)\d*", "\1:", ., perl = TRUE) %>%
strsplit(":") %>%
sapply(function(x) paste(x[grepl("FACT", x)], collapse = " "))
[1] "FACT1" "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2"
[5] "FACT1 FACT2" "FACT1 FACT2" "FACT1 FACT2 FACT3"