【问题标题】:R : How to search for a regex in a vector over elements outwardly?R:如何向外搜索向量中的正则表达式?
【发布时间】:2012-09-03 16:57:40
【问题描述】:

是否可以在 R 中搜索向量中的正则表达式,就好像所有元素都是折叠的单个元素一样?如果我们将所有元素折叠成一个来做到这一点,那么在搜索后就不可能将它们恢复为元素形式。

这是一个向量。

vector<-c("I", "met", "a", "cow")

现在,搜索词是“元”(元素 2 和 3 已折叠)。

假设我的任务是合并搜索字符串所在的两个元素。

所以我的期望是这样的:

vector = "I", "meta", "cow"

可以这样做吗?请帮忙。

【问题讨论】:

  • 为了澄清,您想要:首先,搜索字符串是否存在,其次,返回一个包含合并字符串的新向量。这是正确的吗?
  • 另外,搜索是否总是跨越源中的两个或多个完整字符串?也就是说,您不会搜索“taco”(可以从“met”的最后一个字母开始找到)?
  • @mrdwab 提出了一个很好的观点:如果您想找到“taco”,那么您将拥有“剩余”字符串,而您还没有说要如何处理它们。因此,如果您只想容纳完整的字符串,而不是折叠整个列表,只需成对折叠,例如paste(vector[j],vector[j+1],collapse='') 并对此进行正则表达式。事实上,如果你希望 "taco" 的结果是 "metacow",对结果向量稍作修改仍然可以达到你想要的效果。
  • @mrdwab 对不起,我没有提到这一点,搜索总是跨越完整的字符串。谢谢。

标签: regex r


【解决方案1】:

如果您想要匹配 "meta" 但不匹配 "taco" 的内容,则可以这样做:

myFun <- function(vector, word) {
    D <- "UnLiKeLyStRiNg" 

    ## Construct a string on which you'll perform regex-search
    xx <- paste0(paste0(D, vector, collapse=""), D)

    ## Construct the regex pattern
    start <- paste0("(?<=", D, ")")
    mid <- paste0(strsplit(word, "")[[1]], collapse=paste0("(", D, ")?"))
    end <- paste0("(?=", D, ")")
    pat <- paste0(start, mid, end)

    ## Use it
    strsplit(gsub(pat, word, xx, perl=TRUE), D)[[1]][-1]
}

vector <- c("I", "met", "a", "cow")

myFun(vector, "meta")
# [1] "I"    "meta" "cow" 
myFun(vector, "taco")
# [1] "I"   "met" "a"   "cow"
myFun(vector, "Imet")
# [1] "Imet" "a"    "cow" 
myFun(vector, "Ime")
# [1] "I"   "met" "a"   "cow"

【讨论】:

  • 感谢您再次提供帮助,乔希。得到了我想要的。
【解决方案2】:

如果只合并完整的元素,您可以尝试这种方法:

mergeRegExpr <- function(x, pattern) {
    str <- paste(x, sep="", collapse="")

    ## find starting position of each word
    wordStart <- head(cumsum(c(1, nchar(x))), -1)

    ## look for pattern
    rx <- regexpr(pattern=pattern, text=str, fixed=TRUE)

    ## pos of matching pattern == rx+nchar(pattern)-1
    rxEnd <- rx+attr(rx, "match.length")-1

    ## which vector elements doesn't match pattern
    sel <- wordStart < rx | wordStart > rxEnd

    ## insert merged elements
    return(append(x[sel], paste(x[!sel], collapse=""), rx-1))
}

vector <- c("I", "met", "a", "cow")

mergeRegExpr(vector, "meta")
# "I"    "meta" "cow"
mergeRegExpr(vector, "acow")
# "I"    "met"  "acow"
mergeRegExpr(vector, "Imeta")
# "Imeta" "cow"

## partial matching doesn't work    
mergeRegExpr(vector, "taco")
# "I"       "metacow"

【讨论】:

  • 显然部分匹配确实有效,因为“I metacow”是一个很棒的句子。
【解决方案3】:

基于 Carl Witthoft 的评论,我的解决方案不是使用正则表达式,而是使用基本匹配:

# A slightly longer vector
v = c("I", "met", "a", "cow", "today",
      "You", "met", "a", "cow", "today")

# Create the combinations of each pair
temp1 = sapply(1:(length(v)-1), 
               function(x) paste0(v[x], v[x+1]))

# Grab the index of the desired search term
temp2 = which(temp1 %in% "meta")
# The following also works.
# Don't know what's faster/better.
# temp2 = grep("meta", temp1)

# Do some manual substitution and deletion
v[temp2] <- "meta"
v <- v[-(temp2+1)]

我认为这根本不是一个理想的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-23
    • 2014-12-28
    • 2013-05-06
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2023-02-11
    相关资源
    最近更新 更多