使用 grepl 在 R 中提取子字符串
Posted
技术标签:
【中文标题】使用 grepl 在 R 中提取子字符串【英文标题】:Extract substring in R using grepl 【发布时间】:2019-02-03 06:22:32 【问题描述】:我有一个表格,其中的字符串列格式如下
abcdWorkstart.csv
abcdWorkcomplete.csv
我想提取该文件名中的最后一个单词。所以我认为开始模式是“工作”这个词,结束模式是“.csv”。我用 grepl 写了一些东西,但没有用。
grepl("Work*.csv", data$filename)
基本上我想提取 Work 和 .csv 之间的任何内容
期望的结果:
start
complete
【问题讨论】:
请看看我的编辑@ajax2000。在您的问题中添加所需的结果始终是一个好习惯。这使一切变得如此简单,并且人们确切地知道您想要什么。我鼓励你在下一个问题中这样做;-)。 【参考方案1】:我认为您需要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
【讨论】:
【参考方案2】:来自stringr
的str_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("(?<=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 R
的regmatches/regexpr
的选项。使用正则表达式环视来匹配字符串 'Work' 之后不是 .
的所有字符,使用 regmatches
提取
regmatches(v1, regexpr("(?<=Work)[^.]+(?=[.]csv)", v1, perl = TRUE))
#[1] "start" "complete"
数据
v1 <- c('abcdWorkstart.csv', 'abcdWorkcomplete.csv', 'abcdNothing.csv')
【讨论】:
更准确地说,可以使用"(?<=Work).*(?=.csv)"
。
@avid_user 但是,我使用的是regmatches/regexpr
@AndreElrico,[\\s\\S]
不匹配任何字符吗?使用.
不是更简洁吗?
@r2evans 我同时使用[.]
或\\.
,虽然我觉得前者更容易输入。
这种(以及其他)方法的一个问题是regmatches(...)
不一定与原始向量的索引匹配。例如,输入了三个文件名,出来了两个,但没有直接指示它们属于哪个文件名。 (用另一行或两行代码并不难确定,也不是 regmatches
独有的......虽然我的答案是 NA
的返回是明确的。)以上是关于使用 grepl 在 R 中提取子字符串的主要内容,如果未能解决你的问题,请参考以下文章