184 votes

Extraire une sous-chaîne en fonction d'un motif

Supposons que j'ai une liste de chaînes de caractères :

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

Maintenant, j'espère obtenir un vecteur de chaîne qui ne contient que les parties après les deux points " :", c'est-à-dire substring = c(E001,E002,E003) .

Existe-t-il un moyen pratique de le faire dans R ? Utilisation de substr ?

319voto

G. Grothendieck Points 40825

En voici quelques exemples :

1) sous

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

2) strsplit

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

3) lire.table

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

4) sous-chaîne

Cela suppose que la deuxième partie commence toujours au 4ème caractère (ce qui est le cas dans l'exemple de la question) :

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

4a) substring/regex

Si le colon n'était pas toujours dans une position connue, nous pourrions modifier (4) en le recherchant :

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

5) strapplyc

strapplyc renvoie la partie entre parenthèses :

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

6) lire.dcf

Celle-ci ne fonctionne que si les sous-chaînes précédant les deux-points sont uniques (ce qui est le cas dans l'exemple de la question). Elle exige également que le séparateur soit deux-points (ce qui est le cas dans la question). Si un séparateur différent était utilisé, nous pourrions utiliser sub pour le remplacer par un deux-points en premier. Par exemple, si le séparateur était _ puis string <- sub("_", ":", string)

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

7) séparer

7a) Utilisation de tidyr::separate nous créons un cadre de données avec deux colonnes, une pour la partie avant les deux points et une pour la partie après, puis nous extrayons cette dernière.

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

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

7b) Alternativement separate peut être utilisé pour créer simplement le post et ensuite unlist y unname le cadre de données résultant :

library(dplyr)
library(tidyr)

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

8) trimws Nous pouvons utiliser trimws pour couper les caractères des mots à gauche, puis utilisez-le à nouveau pour couper les deux points.

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

Note

L'entrée string est supposé être :

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

30voto

agstudy Points 55104

Par exemple, en utilisant gsub o sub

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

17voto

CSJCampbell Points 524

En retard sur la fête, mais pour la postérité, les stringr (qui fait partie de la populaire suite de paquets "tidyverse") fournit maintenant des fonctions avec des signatures harmonisées pour la gestion des chaînes de caractères :

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"

15voto

Ragy Isaac Points 471

Voici une autre réponse simple

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

8voto

user1981275 Points 3425

Cela devrait faire l'affaire :

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

donne

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X