R中的grepl:匹配内部短划线的匹配

时间:2015-01-29 19:31:09

标签: regex r lookahead lookbehind grepl

我有3个单词:x,y和z,可以从中构建两个复合词:x-y和y-z。

在自然发生的文本中,x,y和z可以相互跟随。 在第一种情况下,我有:

text="x-y z"

我想检测:" x-y"但不是" y z"。 如果我这样做:

v=c("x-y","y z")
vv=paste("\\b",v,"\\b",sep="")
sapply(vv,grepl,text,perl=TRUE)

我得到c(TRUE,TRUE)。换句话说,grepl没有捕获y已经通过内部短划线链接到x的事实,因此," y z"文本中实际上并不存在。所以我在文本开头添加空格后使用了lookbehind:

text=paste("",text,sep=" ")
vv=paste("(?<= )\\b",v,"\\b",sep="")
sapply(vv,grepl,text,perl=TRUE)

这一次,我得到了我想要的东西:c(TRUE,FALSE)。 现在,在第二种情况下,我有:

text="x y-z"

我想检测&#34; y-z&#34;但不是&#34; x y&#34;。这次采用对称的方法和先行,我尝试了:

text=paste(text,"",sep=" ")
v=c("x y","y-z")
vv=paste("(?= )\\b",v,"\\b",sep="")
sapply(vv,grepl,text,perl=TRUE)

但这次我得到c(FALSE,FALSE)而不是c(FALSE,TRUE),正如我所期待的那样。 预期在第一个位置的FALSE(超前检测到y之后存在字内短划线并且阻止与&#34; x y&#34;的匹配)。但我真的不明白是什么阻止了与&#34; y-z&#34;的匹配。

非常感谢您的帮助,

1 个答案:

答案 0 :(得分:1)

我认为这与您对要完成的内容的评论中的描述相符。

spaceInvader <- function(a, b, text) {
  # look ahead of `a` to see if there is a space
  hasa <- grepl(paste0(a, '(?= )'), text, perl = TRUE)
  # look behind `b` to see if there is a space 
  hasb <- grepl(paste0('(?<= )', b), text, perl = TRUE)

  result <- c(hasa, hasb)
  names(result) <- c(a, b)
  cat('In: "', text, '"\n', sep = '')
  return(result)
}

spaceInvader('x-y', 'y z', 'x-y z')
# In: "x-y z"
#   x-y   y z 
#  TRUE FALSE 
spaceInvader('x y', 'y-z', 'x y-z')
# In: "x y-z"
#   x y   y-z 
# FALSE  TRUE 
spaceInvader('x-y', 'y z', 'x y-z')
# In: "x y-z"
#   x-y   y z 
# FALSE FALSE 
spaceInvader('x y', 'y-z', 'x-y z')
# In: "x-y z"
#   x y   y-z 
# FALSE FALSE 

这是一个问题吗?

spaceInvader('x-y', 'y-z', 'x-y-z')
# In: "x-y-z"
#   x-y   y-z 
# FALSE FALSE