找不到匹配项时,gsub返回空字符串

时间:2012-04-18 17:23:07

标签: regex r grep

我正在使用R中的gsub函数在文本列表中返回我的模式(引用数字)的出现次数。除非找不到匹配项,否则这很有用,在这种情况下,我会返回整个字符串,而不是空字符串。考虑一下这个例子:

data <- list("a sentence with citation (Ref. 12)",
             "another sentence without reference")

sapply(data, function(x) gsub(".*(Ref. (\\d+)).*", "\\1", x))

返回:

[1] "Ref. 12"                            "another sentence without reference"

但我想得到

[1] "Ref. 12"                            ""

谢谢!

7 个答案:

答案 0 :(得分:7)

我可能会走另一条路,因为sapply对我来说似乎没有必要,因为这些函数已经被矢量化了:

fun <- function(x){
    ind <- grep(".*(Ref. (\\d+)).*",x,value = FALSE)
    x <- gsub(".*(Ref. (\\d+)).*", "\\1", x)
    x[-ind] <- ""
    x
}

fun(data)

答案 1 :(得分:4)

根据文档,这是gsub的一个特性,如果没有与提供的模式匹配则返回输入字符串匹配返回整个字符串。

这里,我首先使用函数grepl返回给定字符串中模式存在/不存在的逻辑向量:

ifelse(grepl(".*(Ref. (\\d+)).*", data), 
      gsub(".*(Ref. (\\d+)).*", "\\1", data), 
      "")

将其嵌入函数中:

mygsub <- function(x){
     ans <- ifelse(grepl(".*(Ref. (\\d+)).*", x), 
              gsub(".*(Ref. (\\d+)).*", "\\1", x), 
              "")
     return(ans)
}

mygsub(data)

答案 2 :(得分:1)

xs <- sapply(data, function(x) gsub(".*(Ref. (\\d+)).*", "\\1", x))
xs[xs==data] <- ""
xs
#[1] "Ref. 12" ""       

答案 3 :(得分:1)

在gsubfn包中尝试strapplyc

library(gsubfn)

L <- fn$sapply(unlist(data), ~ strapplyc(x, "Ref. \\d+"))
unlist(fn$sapply(L, ~ ifelse(length(x), x, "")))

给出了这个:

a sentence with citation (Ref. 12) another sentence without reference 
                         "Ref. 12"                                 "" 

如果您不介意列表输出,那么您可以使用L并忘记最后一行代码。请注意,fn$前缀将其应用的函数的公式参数转换为函数调用,因此第一行代码可以在不fn sapply(unlist(data), function(x) strapplyc(x, "Ref x. \\d+"))的情况下编写。

答案 4 :(得分:0)

您可以尝试在该功能中嵌入grep( ..., value = T)

data <- list("a sentence with citation (Ref. 12)",
         "another sentence without reference")

unlist( sapply(data, function(x) { 
  x <- gsub(".*(Ref. (\\d+)).*", "\\1", x)
  grep( "Ref\\.", x, value = T )
  } ) )

有点笨重但有效吗?它还会删除空的第二个引用。

答案 5 :(得分:0)

基于@joran的答案

功能:

extract_matches <- function(x,pattern,replacement,replacement_nomatch=""){
    x <- gsub(pattern,replacement,x)
    x[-grep(pattern,x,value = FALSE)] <- replacement_nomatch
    x
}

用法:

data <- list("with citation (Ref. 12)", "without reference", "")
extract_matches(data,  ".*(Ref. (\\d+)).*", "\\1")

答案 6 :(得分:0)

另一种简单的方法是使用gsub,但要在新函数中指定''

noFalsePositives <- function(a,b,x) {
  return(ifelse(gsub(a,b,x)==x,'',gsub(a,b,x)))
}
# usage
noFalsePositives(".*(Ref. (\\d+)).*", "\\1", data)
# [1] "Ref. 12" ""