regex 根据模式提取子字符串

i7uq4tfw  于 2023-06-25  发布在  其他
关注(0)|答案(9)|浏览(141)

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

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

现在我希望得到一个字符串向量,它只包含冒号“:”之后的部分,即substring = c(E001,E002,E003)
在R中有没有一个方便的方法来做到这一点?使用substr

6jjcrrmo

6jjcrrmo1#

以下是几种方法:

1)sub

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)substring/regex

如果冒号不总是在已知的位置,我们可以通过搜索它来修改(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,我们创建了一个有两列的 Dataframe ,一列用于冒号之前的部分,一列用于冒号之后的部分,然后提取后者。

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

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

**7 b)**也可以使用separate只创建post列,然后unlistunname生成 Dataframe :

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")
6mzjoqzu

6mzjoqzu2#

例如,使用gsubsub

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

at0kjp5o3#

  • *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"
wpcxdonn

wpcxdonn4#

这里有另一个简单的答案

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

gj3fmq9x5#

这应该做到:

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

给予

[1] "E001" "E002" "E003"
5ktev3wc

5ktev3wc6#

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

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

brccelvz7#

  • 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由reprex package(v0.3.0)
更多信息:https://github.com/moodymudskipper/unglue/blob/master/README.md

dauxcl2d

dauxcl2d8#

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

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

ecfsfe2w9#

令人惊讶的是,尚未添加碱R溶液:

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

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

相关问题