У меня есть строковые входы в следующем формате:
my.strings <- c("FACT11", "FACT11:FACT20", "FACT1sometext:FACT20", "FACT1text with spaces:FACT20", "FACT14:FACT20", "FACT1textAnd1312:FACT2etc", "FACT12:FACT22:FACT31")
Я хотел бы извлечь все «ФАКТЫ» и первое число после FACT. Таким образом, результатом этого примера будет:
c("FACT1", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2", "FACT1 FACT2 FACT3")
. Альтернативно, результатом может быть список, в котором каждый элемент списка представляет собой вектор с 1 до 3 элементов.
Я получил до сих пор:
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») и отсутствие «ФАКТ3» для последнего элемента 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, чтобы извлечь всю подстроку «ФАКТ», за которой следует одна цифра, которая может быть от 1 до 3 ([1-3]) в list из vector s. Затем map через элементы list и paste vector s в одну строку
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"
Или используя gsub из base R
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:
Это решение использует факт окончания 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"