在R中使用grepl提取子字符串

10

我有一个带有字符串列的表格,格式如下:

abcdWorkstart.csv
abcdWorkcomplete.csv

我想提取文件名中的最后一个单词。所以我认为开头的模式应该是单词“Work”,结尾的模式应该是“.csv”。我使用了grepl,但没有起作用。

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

基本上我想提取在 Work 和 .csv 之间的任何内容。 期望的结果:
start
complete

3
请看一下我的修改@ajax2000。在问题中添加所需的结果始终是一个好习惯。这样做会使一切变得更加容易,人们也会确切地知道你想要什么。我鼓励你在下一个问题中这样做;-)。 - Andre Elrico
4个回答

10

我认为你需要使用sub或者gsub(替换/提取)来代替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        

7

使用stringr中的str_extract函数。该函数使用正向零宽断言匹配"Work"和".csv"之间的一个或多个字符 (.+):

x <- c("abcdWorkstart.csv", "abcdWorkcomplete.csv")

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

6

作为另一种选择,可以删除您不需要的所有内容。

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("(?<=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


几乎所有的解决方案都可以工作,但我认为这个更加简洁。谢谢。 - ajax2000

5

这里有一个使用base R中的regmatches/regexpr选项。使用正则表达式回溯来匹配字符串“Work”后面不是.的所有字符,并使用regmatches提取。

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

数据

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

1
更精确地说,您可以使用"(?<=Work).*(?=.csv)" - r2evans
@avid_useR 但是,我正在使用regmatches/regexpr - akrun
1
@AndreElrico,[\\s\\S]不是匹配任何字符吗?使用.更加简明吧? - r2evans
1
@r2evans 我同时使用 [.]\\.,不过我觉得前者更容易打。 - akrun
1
这种方法(以及其他方法)的一个问题是,regmatches(...)不一定匹配原始向量的索引。例如,输入了三个文件名,输出了两个,但没有直接指示它们属于哪个文件名。(用另外一行或两行代码很容易确定,而且不仅适用于regmatches ...尽管我的答案返回带有NA是明确无误的。) - r2evans
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接