【问题标题】:Split string at separator using stringr::str_replace使用 stringr::str_replace 在分隔符处拆分字符串
【发布时间】:2019-11-19 00:17:53
【问题描述】:

我需要有关提取由下划线分隔的第三个元素的正则表达式的帮助。下划线的数量是可变的。我可以使用 str_split 来做到这一点,但是有没有办法使用 str_replace 获得与以下相同的结果? (期望的结果是x = AAAA, BBBB, CCCC, DDDD。如果可能的话,使用()维护分组。)

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    

【问题讨论】:

    标签: r regex tidyverse


    【解决方案1】:

    你可以再利用strsplit一点点。

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

    对于整个事情:

    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
    

    【讨论】:

    • 我认为 OP 在他们的尝试中已经实现了这一点。 want_strsplit = str_split(txt, "_", simplify = TRUE)[, 3])
    【解决方案2】:

    sub 的选项

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

    【讨论】:

      【解决方案3】:

      str_replace

      > 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 
      

      第一组捕获_ 的前两次出现。第二组捕获最后一组之后的任何文本。
      如果你也可以有数字,你可以用[[:alnum:]]概括它

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

      【讨论】:

        【解决方案4】:
        d %>%
          mutate(x = str_replace(txt, "^([^_]+)_([^_]+)_([^_]+).*", "\\3"))
        
        • [^_] 代表除了_之外的任何东西

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-01
          • 1970-01-01
          相关资源
          最近更新 更多