簡體   English   中英

如何防止正則匹配丟棄非匹配項?

[英]How to prevent regmatches drop non matches?

我想捕獲第一場比賽,如果沒有比賽則返回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”

繼續使用regexpr

r <- regexpr("a+", x)
out <- rep(NA,length(x))
out[r!=-1] <- regmatches(x, r)
out
#[1] "a"  NA   "a"  "aa"

改用regexec ,因為它返回一個列表,允許您在unlist之前捕獲character(0)

 R <- regmatches(x, regexec("a+", x))
 unlist({R[sapply(R, length)==0] <- NA; R})

 # [1] "a"  NA   "a"  "aa"

在 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)

使用或多或少與您相同的結構-

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]

編輯 - 好像我誤解了這個問題。 但既然有兩個人發現這很有用,我就讓它留下來。

您可以使用stringr::str_extract(string, pattern) 如果沒有匹配,它將返回 NA。 它也具有比regmatches()更簡單的函數接口。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM