我想捕获第一场比赛,如果没有匹配则返回NA
。
regexpr("a+", c("abc", "def", "cba a", "aa"), perl=TRUE)
# [1] 1 -1 3 1
# attr(,"match.length")
# [1] 1 -1 1 2
x <- c("abc", "def", "cba a", "aa")
m <- regexpr("a+", x, perl=TRUE)
regmatches(x, m)
# [1] "a" "a" "aa"
所以我期待“a”,NA,“a”,“aa”
答案 0 :(得分:15)
坚持regexpr
:
r <- regexpr("a+", x)
out <- rep(NA,length(x))
out[r!=-1] <- regmatches(x, r)
out
#[1] "a" NA "a" "aa"
答案 1 :(得分:10)
使用regexec
代替,因为它返回一个列表,可以让您在character(0)
之前捕获unlist
R <- regmatches(x, regexec("a+", x))
unlist({R[sapply(R, length)==0] <- NA; R})
# [1] "a" NA "a" "aa"
答案 2 :(得分:6)
在R 3.3.0中,可以使用invert = NA参数拉出匹配和不匹配的结果。从帮助文件中可以看出
如果反转是NA,则regmatches提取非匹配和匹配的子串,始终以不匹配开始和结束(如果匹配分别在开头或结尾发生,则为空)。
输出是一个列表,通常,在大多数情况下感兴趣,(匹配单个模式),regmatches
与此参数将返回一个长度为3或1的元素的列表.1是的情况下没有找到匹配的地方,3是匹配的情况。
myMatch <- regmatches(x, m, invert=NA)
myMatch
[[1]]
[1] "" "a" "bc"
[[2]]
[1] "def"
[[3]]
[1] "cb" "a" " a"
[[4]]
[1] "" "aa" ""
因此,要提取您想要的内容(使用&#34;&#34;代替NA),您可以使用sapply
,如下所示:
myVec <- sapply(myMatch, function(x) {if(length(x) == 1) "" else x[2]})
myVec
[1] "a" "" "a" "aa"
此时,如果你真的想要NA而不是&#34;&#34;,你可以使用
is.na(myVec) <- nchar(myVec) == 0L
myVec
[1] "a" NA "a" "aa"
一些修订:
请注意,您可以将最后两行折叠为一行:
myVec <- sapply(myMatch, function(x) {if(length(x) == 1) NA_character_ else x[2]})
NA
的默认数据类型是合乎逻辑的,因此使用它将导致额外的数据转换。使用字符版本NA_character_
可以避免这种情况。
最后一行的更加流畅的提取方法是使用[
:
sapply(myMatch, `[`, 2)
[1] "a" NA "a" "aa"
所以你可以用一个相当可读的单行来完成整个事情:
sapply(regmatches(x, m, invert=NA), `[`, 2)
答案 3 :(得分:1)
使用或多或少与你相同的结构 -
chars <- c("abc", "def", "cba a", "aa")
chars[
regexpr("a+", chars, perl=TRUE) > 0
][1] #abc
chars[
regexpr("q", chars, perl=TRUE) > 0
][1] #NA
#vector[
# find all indices where regexpr returned positive value i.e., match was found
#][return the first element of the above subset]
编辑 - 似乎我误解了这个问题。但由于两个人发现这个有用,我会让它留下来。