根据模式提取子字符串

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

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

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

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

322057 次浏览

例如使用 gsubsub

    gsub('.*:(.*)','\\1',string)
[1] "E001" "E002" "E003"

以下是一些方法:

1)小组

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

2) strsplit

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"

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

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

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

5) strappyc

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)分开

使用 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"

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

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

注意

假定输入 string为:

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

这应该可以:

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

给予

[1] "E001" "E002" "E003"

这是另一个简单的答案

gsub("^.*:","", string)

Stringr软件包(流行的“整齐宇宙”软件包的一部分)现在为字符串处理提供了具有协调签名的功能:

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"

如果你使用 data.table,那么 tstrsplit()是一个自然的选择:

tstrsplit(string, ":")[[2]]
[1] "E001" "E002" "E003"

解开胶水包提供了另一种选择,对于简单的情况,不需要正则表达式的知识,这里我们要做的是:

# 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 软件包于2019-11-06年度创作(0.3.0版)

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

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

library(stringr)
substring <- str_extract(string, regex("(?<=:).*"))
#[1] "E001" "E002" "E003
  • 看结肠后面(:)

令人惊讶的是,一个非常“基础 R”的解决方案还没有被添加:

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


regmatches(string, regexpr('E[0-9]+', string))