【问题标题】:Extract part of string before the first semicolon在第一个分号之前提取部分字符串
【发布时间】:2015-04-20 15:36:31
【问题描述】:

我有一列包含由分号分隔的 3 个字符串的值。我只需要提取第一个分号之前的字符串部分

Type <- c("SNSR_RMIN_PSX150Y_CSH;SP_12;I0.00V50HX0HY3000")

我想要的是:获取字符串的第一部分(直到第一个分号)。

所需输出: SNSR_RMIN_PSX150Y_CSH

我尝试gsub 没有成功。

【问题讨论】:

    标签: r string gsub


    【解决方案1】:

    你可以试试sub

    sub(';.*$','', Type)
    #[1] "SNSR_RMIN_PSX150Y_CSH"
    

    它将匹配模式,即;的第一次出现到字符串的末尾并替换为''

    或者使用

    library(stringi)
    stri_extract(Type, regex='[^;]*')
    #[1] "SNSR_RMIN_PSX150Y_CSH"
    

    【讨论】:

    • 谢谢。即使处理大型数据集也能快速运行。
    • @Sharath 没问题。我认为stringi 应该更快。更新了一个选项,请检查是否很快
    • 我认为您在stri_extract 中的正则表达式应该是'^[^;]*',以明确表示您想要; 之前的第一组字符...
    • @StevieP 谢谢,我想过改变它,但后来 TylerRinker 也发布了一个解决方案,所以我就这样离开了。但是,我不确定这是否会在任何情况下失败。
    • @akrun 您能解释一下正则表达式中 * 或 + 符号之间的区别吗?你使用 * 但下面他使用 +。
    【解决方案2】:

    stringi 包在这里工作得非常快:

    stri_extract_first_regex(Type, "^[^;]+")
    ## [1] "SNSR_RMIN_PSX150Y_CSH"
    

    我在这里对 3 种主要方法进行了基准测试:

    Unit: milliseconds
          expr       min        lq      mean   median        uq      max neval
      SAPPLY() 254.88442 267.79469 294.12715 277.4518 325.91576 419.6435   100
         SUB() 182.64996 186.26583 192.99277 188.6128 197.17154 237.9886   100
     STRINGI()  89.45826  91.05954  94.11195  91.9424  94.58421 124.4689   100
    

    这是基准测试的代码:

    library(stringi)
    SAPPLY <- function() sapply(strsplit(Type, ";"), "[[", 1)
    SUB <- function() sub(';.*$','', Type)
    STRINGI <- function() stri_extract_first_regex(Type, "^[^;]+")
    
    Type <- c("SNSR_RMIN_PSX150Y_CSH;SP_12;I0.00V50HX0HY3000")
    Type <- rep(Type, 100000)
    
    library(microbenchmark)
    microbenchmark( 
        SAPPLY(),
        SUB(),
        STRINGI(),
    times=100L)
    

    【讨论】:

    • 我错过了 akrun 的编辑(与我的方法大致相同)我将离开进行基准测试
    • 谢谢泰勒。 'stringi' 库很快,我将使用它而不是 sub。
    • 在使用stri_extract_first_regexstri_extract 并在里面指定正则表达式会有什么不同吗?
    • 我不确定,但文档明确指出:“stri_extract、stri_extract_all、stri_extract_first 和 stri_extract_last 是便利函数。它们只是调用 stri_extract__,具体取决于使用的参数。除非你是个很懒的人,请直接调用底层函数以获得更好的性能。”
    【解决方案3】:

    你也可以使用strsplit

    strsplit(Type, ";")[[1]][1]
    [1] "SNSR_RMIN_PSX150Y_CSH"
    

    【讨论】:

      【解决方案4】:

      当性能很重要时,您可以将 substrbase 中的 regexpr 结合使用。

      substr(Type, 1, regexpr(";", Type, fixed=TRUE)-1)
      #[1] "SNSR_RMIN_PSX150Y_CSH"
      

      时间安排:(重用来自@tyler-rinker 的部分)

      library(stringi)
      SAPPLY <- function() sapply(strsplit(Type, ";"), "[[", 1)
      SUB <- function() sub(';.*$','', Type)
      SUB2 <- function() sub(';.*','', Type)
      SUB3 <- function() sub('([^;]*).*','\\1', Type)
      STRINGI <- function() stri_extract_first_regex(Type, "^[^;]+")
      STRINGI2 <- function() stri_extract_first_regex(Type, "[^;]*")
      SUBSTRREG <- function() substr(Type, 1, regexpr(";", Type)-1)
      SUBSTRREG2 <- function() substr(Type, 1, regexpr(";", Type, fixed=TRUE)-1)
      SUBSTRREG3 <- function() substr(Type, 1, regexpr(";", Type, fixed=TRUE, useBytes = TRUE)-1)
      
      Type <- c("SNSR_RMIN_PSX150Y_CSH;SP_12;I0.00V50HX0HY3000")
      Type <- rep(Type, 100000)
      
      library(microbenchmark)
      microbenchmark(SAPPLY(), SUB(), SUB2(), SUB3(), STRINGI()
       , STRINGI2(), SUBSTRREG(), SUBSTRREG2(), SUBSTRREG3())
      #Unit: milliseconds
      #         expr       min        lq      mean    median        uq       max neval
      #     SAPPLY() 382.23750 395.92841 412.82508 410.05236 427.58816 460.28508   100
      #        SUB() 111.92120 114.28939 116.41950 115.57371 118.15573 123.92400   100
      #       SUB2()  94.27831  96.50462  98.14741  97.38199  99.15260 119.51090   100
      #       SUB3() 167.77139 172.51271 175.07144 173.83121 176.27710 190.97815   100
      #    STRINGI()  38.27645  39.33428  39.94134  39.71842  40.50182  42.55838   100
      #   STRINGI2()  38.16736  39.19250  40.14904  39.63929  40.37686  56.03174   100
      #  SUBSTRREG()  45.04828  46.39867  47.13018  46.85465  47.71985  51.07955   100
      # SUBSTRREG2()  10.67439  11.02963  11.29290  11.12222  11.43964  13.64643   100
      # SUBSTRREG3()  10.74220  10.95139  11.39466  11.06632  11.46908  27.72654   100
      

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 2016-09-05
        • 1970-01-01
        • 2012-02-06
        • 2019-07-29
        • 2015-08-15
        • 2023-03-10
        • 2012-09-19
        • 1970-01-01
        相关资源
        最近更新 更多