Как бы удалить текст до начала периода, сам начальный период и текст после последнего периода в строке? - PullRequest
2 голосов
/ 07 октября 2019

Мне нужно удалить текст перед начальным периодом (а также начальным периодом) и текст, следующий за последним периодом из строки.

Для этой строки, например:

"ABCD.EF.GH.IJKL.MN"

Я хотел бы получить вывод:

[1] "IJKL"

Я пробовал следующее:

split_string <- sub("^.*?\\.","", string)

split_string <- sub("^\\.+|\\.[^.]*$", "", string)

Я считаю, что он работает для периода и текст после этоговывод строки я хочу. Однако первую строку необходимо выполнить несколько раз, чтобы удалить текст до рассматриваемого периода, например «.I».

Ответы [ 4 ]

1 голос
/ 07 октября 2019

Один вариант в base R состоит в том, чтобы захватить в виде группы ((...)) слово, за которым следуют точка (\\.) и слово (\\w+) до конца ($) строки,При замене используйте обратную ссылку (\\1) захваченного слова

sub(".*\\.(\\w+)\\.\\w+$", "\\1", str1)
#[1] "IJKL"

. Здесь мы сопоставляем символы (.*) до тех пор, пока . (\\.) не получится, чтобы получить литералзначение, потому что . является метасимволом, который будет соответствовать любому символу, если не экранирован), за которым следует захваченное слово ((\\w+)), за которым следуют точка и другое слово в конце ($) строки. Запасная часть упомянута выше


Или другой вариант regmatches/regexpr из base R

regmatches(str1, regexpr("\\w+(?=\\.\\w+$)", str1, perl = TRUE))
#[1] "IJKL"

Или другой вариант word из stringr

library(stringr)
word(str1, -2, sep="[.]")
#[1] "IJKL"

данные

str1 <- "ABCD.EF.GH.IJKL.MN"
0 голосов
/ 07 октября 2019

Вот версия janky dplyr на случай, если другие значения важны, и вы хотите выбрать их позже, просто включите их в «select».

df<- data.frame(x=c("ABCD.EF.GH.IJKL.MN"))
df2<-df %>%
  separate(x, into=c("var1", "var2","var3","var4","var5")) %>%
  select("var4")
0 голосов
/ 07 октября 2019

Разбейте на группы по периодам и возьмите вторую из последних.

sapply(strsplit(str1, "\\."), function(x) x[length(x) - 1])
#[1] "IJKL"

Получите индексы периодов и используйте substr, чтобы извлечь соответствующую часть

sapply(str1, function(x){
    ind = gregexpr("\\.", x)[[1]]
    substr(x, ind[length(ind) - 1] + 1, ind[length(ind)] - 1)
}, USE.NAMES = FALSE)
#[1] "IJKL"
0 голосов
/ 07 октября 2019

Все эти альтернативы не используют никаких пакетов или регулярных выражений.

1) basename / dirname Предполагая, что тестовый ввод s, показанный в примечании в конце, преобразует точки в косые черты изатем используйте dirname и basename.

basename(dirname(chartr(".", "/", s)))
## [1] "IJKL" "IJKL"

2) strsplit Использование strsplit разбивает строки по точкам, создавая список векторов символов, по одному вектору на входную строку,и затем для каждого такого вектора возьмите последние 2 элемента, используя tail, и первый из тех, которые используют индексацию.

sapply(strsplit(s, ".", fixed = TRUE), function(x) tail(x, 2)[1])
## [1] "IJKL" "IJKL"

3) read.table Это не ясно из вопросав общем случае, но если все компоненты s имеют одинаковое количество полей, разделенных точками, то мы можем использовать read.table для создания data.frame с одной строкой на входную строку и одним столбцом на компонент, разделенный точками. Затем возьмите столбец непосредственно перед последним.

dd <- read.table(text = s, sep = ".", as.is = TRUE)
dd[[ncol(dd)-1]]
## [1] "IJKL" "IJKL"

4) substr Опять же, общий случай неясен, но если интересующая строка всегда находится в позициях символов 12-15, топростое решение:

substr(s, 12, 15)
## [1] "IJKL" "IJKL"

Примечание

s <- c("ABCD.EF.GH.IJKL.MN", "ABCD.EF.GH.IJKL.MN")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...