160

假设我有一个字符串列表:

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

现在我希望得到一个字符串向量,它只包含冒号“:”之后的部分,即substring = c(E001,E002,E003)

R中有没有方便的方法来做到这一点?使用substr?

4

9 回答 9

285

这里有几种方法:

1) 子

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

2)strsplit

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

3) 读表

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

4) 子串

这假设第二部分总是从第 4 个字符开始(问题示例中就是这种情况):

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

4a) 子字符串/正则表达式

如果冒号并不总是在已知位置,我们可以通过搜索来修改 (4):

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

5) 绑带式

strapplyc返回带括号的部分:

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

6) 读取.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然后创建结果数据框:unlistunname

library(dplyr)
library(tidyr)

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

8) trimws我们可以用trimws它来修剪左边的单词字符,然后再用它来修剪冒号。

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

笔记

假设输入string为:

string <- c("G1:E001", "G2:E002", "G3:E003")
于 2013-06-20T14:10:47.070 回答
30

例如使用gsubsub

    gsub('.*:(.*)','\\1',string)
    [1] "E001" "E002" "E003"
于 2013-06-20T14:10:10.470 回答
14

这是另一个简单的答案

gsub("^.*:","", string)
于 2014-04-21T19:49:19.293 回答
12

晚了,但为了后代,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"
于 2018-10-02T12:47:57.010 回答
6

这应该这样做:

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

[1] "E001" "E002" "E003"
于 2013-06-20T14:10:54.670 回答
6

如果您正在使用data.tablethentstrsplit()是一个自然的选择:

tstrsplit(string, ":")[[2]]
[1] "E001" "E002" "E003"
于 2018-10-02T12:51:54.503 回答
5

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"

reprex 包(v0.3.0)于 2019-11-06 创建

更多信息:https ://github.com/moodymudskipper/unglue/blob/master/README.md

于 2019-11-06T11:11:26.910 回答
2

另一种提取子字符串的方法

library(stringr)
substring <- str_extract(string, regex("(?<=:).*"))
#[1] "E001" "E002" "E003
  • (?<=:): 看冒号后面 ( :)
于 2020-08-10T03:04:52.653 回答
1

令人惊讶的是,尚未添加非常“基本 R”的解决方案:

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

regmatches(string, regexpr('E[0-9]+', string))
于 2021-05-20T13:41:25.093 回答