【问题标题】:Extract string between /提取/之间的字符串
【发布时间】:2012-12-18 06:07:34
【问题描述】:

如果我有这些字符串:

mystrings <- c("X2/D2/F4",
               "X10/D9/F4",
               "X3/D22/F4",
               "X9/D22/F9")

如何提取2,9,22,22。这些字符位于// 中的第一个字符之后。

我想以矢量化方式执行此操作,并在我熟悉的情况下添加带有transfrom 的新列。

我认为这个正则表达式让我接近\ 中的所有字符:

^.*\\'(.*)'\\.*$

【问题讨论】:

  • +1 for all @Arun 给了我第一个可行的答案。我只是不够用字符串。

标签: r regex


【解决方案1】:
> gsub("(^.+/[A-Z]+)(\\d+)(/.+$)", "\\2", mystrings)
[1] "2"  "9"  "22" "22"

你会“读取”(或“解析”)正则表达式模式,将任何匹配的字符串分成三个部分:

1) 任何内容,包括第一个正斜杠后跟一系列大写字母,

2) 序列中下一个斜杠和 , 之前的任何数字(= "\d")

3) 从下一个斜杠到结尾。

然后只返回第二部分....

不匹配的字符串将原样返回。

【讨论】:

  • +1 我不知道你可以在没有第二组的情况下用\\2 抢到第二组!光滑。
【解决方案2】:

as.numeric(gsub("^.*D([0-9]+).*$", "\\1", mystrings))

【讨论】:

    【解决方案3】:

    @Arun 抢了我的风头,所以我给出了我最初的冗长示例。

    cut.to.pieces <- strsplit(mystrings, split = "/")
    got.second <- lapply(cut.to.pieces, "[", 2)
    get.numbers <- unlist(got.second)
    as.numeric(gsub(pattern = "[[:alpha:]]", replacement = "", x = get.numbers, perl = TRUE))
    [1]  2  9 22 22
    

    【讨论】:

      【解决方案4】:

      使用stringr 包中的str_extract

      as.numeric(str_extract(mystrings, perl('(?<=/[A-Z])[0-9]+(?=/)')))
      

      【讨论】:

      • @rrs 这是后视断言的一部分。在 R 提示符中输入 ?regex 并阅读“类 Perl 正则表达式”部分的最后几段。
      【解决方案5】:

      这最终成为@RomanLuštrik 答案的压缩版本:

      gsub("[^0-9]","",sapply(strsplit(mystrings,"/"),"[",2))
      [1] "2"  "9"  "22" "22"
      

      【讨论】:

        【解决方案6】:

        使用rex 可能会使这类任务更简单一些。

        matches <- re_matches(mystrings,
          rex(
            "/",
            any,
            capture(name = "numbers", digits)
            )
          )
        
        as.numeric(matches$numbers)
        #>[1]  2  9 22 22
        

        【讨论】:

          【解决方案7】:

          使用包脱胶你可以做到:

          # install.packages("unglue")
          library(unglue)
          
          unglue_vec(mystrings, "{x}/{y}/{z}", var = "y")
          #> [1] "D2"  "D9"  "D22" "D22"
          

          您可以从数据框中使用unglue_unnest(),因此无需使用transform()

          df <- data.frame(col = mystrings)
          unglue_unnest(df, col, "{x}/{y}/{z}", remove = FALSE)
          #>         col   x   y  z
          #> 1  X2/D2/F4  X2  D2 F4
          #> 2 X10/D9/F4 X10  D9 F4
          #> 3 X3/D22/F4  X3 D22 F4
          #> 4 X9/D22/F9  X9 D22 F9
          
          # or used unnamed subpatterns to keep only the middle value
          unglue_unnest(df, col, "{=.*?}/{y}/{=.*?}", remove = FALSE)
          #>         col   y
          #> 1  X2/D2/F4  D2
          #> 2 X10/D9/F4  D9
          #> 3 X3/D22/F4 D22
          #> 4 X9/D22/F9 D22
          

          reprex package (v0.3.0) 于 2019 年 11 月 6 日创建

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-11-26
            • 2021-09-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-05
            • 1970-01-01
            相关资源
            最近更新 更多