Извлечь подстроку в соответствии с шаблоном

136

Предположим, у меня есть список строк:

string = c("G1:E001", "G2:E002", "G3:E003")

Теперь я надеюсь получить вектор строки , которая содержит только части после двоеточия «:», то есть substring = c(E001,E002,E003).

Есть ли в R удобный способ сделать это? Используете substr?

маленький мальчик
источник

Ответы:

239

Вот несколько способов:

1) суб

sub(".*:", "", string)
## [1] "E001" "E002" "E003"

2) Стрсплит

sapply(strsplit(string, ":"), "[", 2)
## [1] "E001" "E002" "E003"

3) read.table

read.table(text = string, sep = ":", as.is = TRUE)$V2
## [1] "E001" "E002" "E003"

4) подстрока

Это предполагает, что вторая часть всегда начинается с 4-го символа (что имеет место в примере в вопросе):

substring(string, 4)
## [1] "E001" "E002" "E003"

4а) подстрока / регулярное выражение

Если бы двоеточие не всегда было в известной позиции, мы могли бы изменить (4), выполнив его поиск:

substring(string, regexpr(":", string) + 1)

5) страпплик

strapplyc возвращает часть в скобках:

library(gsubfn)
strapplyc(string, ":(.*)", simplify = TRUE)
## [1] "E001" "E002" "E003"

6) read.dcf

Этот работает, только если подстроки перед двоеточием уникальны (что они в примере в вопросе). Также требуется, чтобы разделитель был двоеточием (о чем идет речь). Если бы использовался другой разделитель, то мы могли бы subсначала заменить его двоеточием. Например, если разделитель был _тогдаstring <- sub("_", ":", string)

c(read.dcf(textConnection(string)))
## [1] "E001" "E002" "E003"

7) отдельный

7a) Используя, tidyr::separateмы создаем фрейм данных с двумя столбцами, один для части до двоеточия и один для после, а затем извлекаем последний.

library(dplyr)
library(tidyr)
library(purrr)

DF <- data.frame(string)
DF %>% 
  separate(string, into = c("pre", "post")) %>% 
  pull("post")
## [1] "E001" "E002" "E003"

7b) В качестве альтернативы separateможно просто создать postстолбец, а затем unlistи unnameрезультирующий кадр данных:

library(dplyr)
library(tidyr)

DF %>% 
  separate(string, into = c(NA, "post")) %>% 
  unlist %>%
  unname
## [1] "E001" "E002" "E003"

8) Обрезки Мы можем использовать trimwsдля обрезки слов слева и затем снова использовать для обрезки двоеточия.

trimws(trimws(string, "left", "\\w"), "left", ":")
## [1] "E001" "E002" "E003"

Заметка

Предполагается, что входные данные string:

string <- c("G1:E001", "G2:E002", "G3:E003")
Г. Гротендик
источник
У меня была переменная в расплавленной таблице, которая имела _разделитель и сделала две отдельные переменные для префикса и суффикса на основе ответа @Grothendieck: prefix <- sub("_.*", "", variable)и suffix <- sub(".*_", "", variable)
swihart
Было бы неплохо увидеть микробенчмаркинг этого удивительного ответа!
patL
25

Например, используя gsubилиsub

    gsub('.*:(.*)','\\1',string)
    [1] "E001" "E002" "E003"
agstudy
источник
не могли бы вы объяснить, что это такое? * (* и так далее, точно ли? Я с трудом воссоздаю это только в немного другой обстановке ...
Питер Пэн,
1
@PeterPan Захватывает и возвращает группу символов после двоеточия. Если подходящие строки сложнее и вы хотите остаться в базе R, это хорошо работает.
Кларк Фицджеральд
14

Вот еще один простой ответ

gsub("^.*:","", string)
Рэги Исаак
источник
9

Поздно, но для потомков, пакет stringr (часть популярного пакета «tidyverse») теперь предоставляет функции с согласованными сигнатурами для обработки строк:

string <- c("G1:E001", "G2:E002", "G3:E003")
# match string to keep
stringr::str_extract(string = string, pattern = "E[0-9]+")
# [1] "E001" "E002" "E003"

# replace leading string with ""
stringr::str_remove(string = string, pattern = "^.*:")
# [1] "E001" "E002" "E003"
CSJCampbell
источник
2
Разве это не нахождение первого числа, начинающегося с E, а не всего после двоеточия?
Марк Нил
6

Это должно сделать:

gsub("[A-Z][1-9]:", "", string)

дает

[1] "E001" "E002" "E003"
user1981275
источник
3

Если вы используете, data.tableто tstrsplit()это естественный выбор:

tstrsplit(string, ":")[[2]]
[1] "E001" "E002" "E003"
sindri_baldur
источник
3

Пакет unglue предоставляет альтернативу, для простых случаев никаких знаний о регулярных выражениях не требуется, вот что мы сделаем:

# install.packages("unglue")
library(unglue)
string = c("G1:E001", "G2:E002", "G3:E003")
unglue_vec(string,"{x}:{y}", var = "y")
#> [1] "E001" "E002" "E003"

Создано 2019-11-06 пакетом представлением (v0.3.0)

Дополнительная информация: https://github.com/moodymudskipper/unglue/blob/master/README.md

Moody_Mudskipper
источник