在 R 3.3.0 中,可以使用 invert=NA 参数同时提取匹配和不匹配的结果。从帮助文件中,它说
如果 invert 为 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" ""
所以要提取你想要的(用“”代替NA),你可以使用sapply
如下:
myVec <- sapply(myMatch, function(x) {if(length(x) == 1) "" else x[2]})
myVec
[1] "a" "" "a" "aa"
此时,如果你真的想要 NA 而不是 "",你可以使用
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)