1
votes

Diviser la chaîne au séparateur en utilisant stringr :: str_replace

J'ai besoin d'aide concernant une expression régulière qui extrait le troisième élément séparé par un trait de soulignement. Le nombre de traits de soulignement est variable. Je peux le faire en utilisant str_split, mais y a-t-il un moyen d'obtenir le même résultat que ci-dessous en utilisant str_replace? (Le résultat souhaité est x = AAAA, BBBB, CCCC, DDDD . Si possible, maintenir le regroupement en utilisant () .)

library(tidyverse)
library(stringr)

d <- enframe(c("asfe_01_AAAA_fses_feee",
               "asfe_87_BBBB_fses_feee",
               "99_fesf_CCCC_feee",
               "99_fesf_DDDD"),
             name = NULL, value = "txt")

d %>%
  mutate(x = str_replace(txt, "(.+)_(.+)_(.+)_*(.*)_*(.*)", "\\3"),
         want_strsplit = str_split(txt, "_", simplify = TRUE)[, 3])

#txt                    x     want_strsplit
#  <chr>                  <chr> <chr>        
#1 asfe_01_AAAA_fses_feee feee  AAAA         
#2 asfe_87_BBBB_fses_feee feee  BBBB         
#3 99_fesf_CCCC_feee      feee  CCCC         
#4 99_fesf_DDDD           DDDD  DDDD    

p >


0 commentaires

4 Réponses :


5
votes

Vous pouvez simplement exploiter un peu plus strsplit .

splt <- strsplit(d$txt, "_")
cbind(d, x=mapply(`[`, splt, lengths(splt)), want_strsplit=mapply(`[`, splt, 3))
#                      txt    x want_strsplit
# 1 asfe_01_AAAA_fses_feee feee          AAAA
# 2 asfe_87_BBBB_fses_feee feee          BBBB
# 3      99_fesf_CCCC_feee feee          CCCC
# 4           99_fesf_DDDD DDDD          DDDD

Pour l'ensemble:

mapply(`[`, strsplit(d$txt, "_"), 3)
# [1] "AAAA" "BBBB" "CCCC" "DDDD"

p>


1 commentaires

Je pense qu'OP avait déjà réussi cela dans leur tentative. want_strsplit = str_split (txt, "_", simplify = TRUE) [ 3])



3
votes

Avec str_replace

d%>%mutate(x=str_replace(txt,"^((?:[^_]*_){2})([[:alnum:]]+).*","\\2"))

Le premier groupe capture les deux premières occurrences de _ . Le deuxième groupe capture tout texte après le dernier groupe.
Dans le cas où vous pouvez également avoir des nombres, vous pouvez le généraliser avec [[: alnum:]]

> d%>%mutate(x=str_replace(txt,"^((?:[^_]*_){2})([a-zA-Z]+).*","\\2"))
# A tibble: 4 x 2
  txt                    x    
  <chr>                  <chr>
1 asfe_01_AAAA_fses_feee AAAA 
2 asfe_87_BBBB_fses_feee BBBB 
3 99_fesf_CCCC_feee      CCCC 
4 99_fesf_DDDD           DDDD 


0 commentaires

3
votes

Une option avec sub

sub("^(([^_]+_){2})([^_]+).*", "\\3", d$txt)
#[1] "AAAA" "BBBB" "CCCC" "DDDD"


0 commentaires

2
votes
d %>%
  mutate(x = str_replace(txt, "^([^_]+)_([^_]+)_([^_]+).*", "\\3"))

[^_] standing for anything except _

0 commentaires