【问题标题】:Extract substring in R using grepl使用 grepl 在 R 中提取子字符串
【发布时间】:2019-02-03 06:22:32
【问题描述】:

我有一个表格,其中的字符串列格式如下

abcdWorkstart.csv
abcdWorkcomplete.csv

我想提取该文件名中的最后一个单词。所以我认为开始模式是“工作”这个词,结束模式是“.csv”。我用 grepl 写了一些东西,但没有用。

grepl("Work{*}.csv", data$filename)

基本上我想提取 Work 和 .csv 之间的任何内容

期望的结果:

start
complete

【问题讨论】:

  • 请看看我的编辑@ajax2000。在您的问题中添加所需的结果始终是一个好习惯。这使一切变得如此简单,并且人们确切地知道您想要什么。我鼓励你在下一个问题中这样做;-)。

标签: r string dataframe substring


【解决方案1】:

我认为您需要subgsub(替换/提取)而不是grepl(查找是否存在匹配项)。请注意,当没有找到时,它将返回未修改的整个字符串:

fn <- c('abcdWorkstart.csv', 'abcdWorkcomplete.csv', 'abcdNothing.csv')
out <- sub(".*Work(.*)\\.csv$", "\\1", fn)
out
# [1] "start"           "complete"        "abcdNothing.csv"

您可以通过过滤掉未更改的内容来解决此问题:

out[ out != fn ]
# [1] "start"    "complete"

或者用NA(或其他东西)将它们标记为无效:

out[ out == fn ] <- NA
out
# [1] "start"    "complete" NA        

【讨论】:

    【解决方案2】:

    来自stringrstr_extract。这使用正向环视来匹配“Work”和“.csv”之间的任何字符一次或多次 (.+):

    x <- c("abcdWorkstart.csv", "abcdWorkcomplete.csv")
    
    library(stringr)
    str_extract(x, "(?<=Work).+(?=\\.csv)")
    # [1] "start"    "complete"
    

    【讨论】:

      【解决方案3】:

      作为一种替代方法,删除您不想要的所有内容。

      x <- c("abcdWorkstart.csv", "abcdWorkcomplete.csv")
      
      gsub("^.*Work|\\.csv$", "", x)
      #[1] "start"    "complete"
      

      请注意: 我必须使用gsub。因为我先删除^.*Work,然后删除\\.csv$


      对于[\\s\\S]\\d\\D ...(不适用于[g]?sub)

      https://regex101.com/r/wFgkgG/1

      使用 akruns 方法:

      regmatches(v1, regexpr("(?&lt;=Work)[\\s\\S]+(?=[.]csv)", v1, perl = T))

      str1<-
      '12
      .2
      12'
      
      gsub("[^.]","m",str1,perl=T)
      gsub(".","m",str1,perl=T)
      gsub(".","m",str1,perl=F)
      

      . 在使用 R 引擎时也匹配 \n

      【讨论】:

      • 几乎所有解决方案都有效,但我认为这更简洁。谢谢
      【解决方案4】:

      这是一个使用来自base Rregmatches/regexpr 的选项。使用正则表达式环视来匹配字符串 'Work' 之后不是 . 的所有字符,使用 regmatches 提取

      regmatches(v1, regexpr("(?<=Work)[^.]+(?=[.]csv)", v1, perl = TRUE))
      #[1] "start"    "complete"
      

      数据

      v1 <- c('abcdWorkstart.csv', 'abcdWorkcomplete.csv', 'abcdNothing.csv')
      

      【讨论】:

      • 更准确地说,可以使用"(?&lt;=Work).*(?=.csv)"
      • @avid_user 但是,我使用的是regmatches/regexpr
      • @AndreElrico,[\\s\\S] 不匹配任何字符吗?使用.不是更简洁吗?
      • @r2evans 我同时使用[.]\\.,虽然我觉得前者更容易输入。
      • 这种(以及其他)方法的一个问题是regmatches(...) 不一定与原始向量的索引匹配。例如,输入了三个文件名,出来了两个,但没有直接指示它们属于哪个文件名。 (用另一行或两行代码并不难确定,也不是 regmatches 独有的......虽然我的答案是 NA 的返回是明确的。)
      猜你喜欢
      • 1970-01-01
      • 2022-01-17
      • 2020-12-17
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多