1

假设有一个形式为"foo"or的序列向量"foo|baz|bar"(一个单词或多个单词,由特殊字符 like 分隔"|"),并且我们还给定了一个单词,我们想找出它与向量的哪些项目与整个单词匹配。

例如,单词"foo"在 中有一个完整的匹配项,但在or"foo|baz|bar"中没有一个完整的匹配项。"foobaz|bar""bazfoo"

首先,我尝试使用"\\b"它来指示整个单词的开始或结束边缘,并且它成功地工作:

grep("\\bfoo\\b", "foo")         # match
grep("\\bfoo\\b", "foobaz|bar")  # mismatch    
grep("\\bfoo\\b", "bazfoo")      # mismatch

然后我尝试添加"|"作为两端的另一个可能的分隔符,并"\\b"使用[and将其分组]

grep("[|\\b]foo[|\\b]", "foo|baz|bar")  # mismatch!
grep("[|\\b]foo[|\\b]", "foo")          # mismatch!

后来我发现\\b不是字符串的开头结尾,|-^.的指示符,而是整个单词的开头或结尾(很多字符,如空格而不是数字和下划线_分隔整个单词)。所以"[|\\b]foo[|\\b]"匹配所有这些字符串:"foo", "foo|bar|baz", "foo-bar", "baz foo|bar"但不匹配"foo_bar"or "foo2"

但我的问题仍然存在:为什么"[|\\b]foo[|\\b]"模式无法匹配"foo"

4

4 回答 4

3

你可以使用strplit

> "foo" %in% unlist(strsplit("foo|baz|bar", split = "|", fixed = TRUE))
[1] TRUE

您可以对其进行矢量化:

> z <- c("foo|baz|bar", "foobaz|bar", "bazfoo")
> x <- c("foo", "foot")
> sapply(strsplit(z, split = "|", fixed = TRUE), function(x,y)y %in% x, x)
      [,1]  [,2]  [,3]
[1,]  TRUE FALSE FALSE
[2,] FALSE FALSE FALSE
于 2012-10-14T18:37:44.503 回答
2

\b 匹配以下位置

  1. 在字符串的第一个字符之前,如果第一个字符是单词字符。
  2. 在字符串的最后一个字符之后,如果最后一个字符是单词字符。
  3. 在字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符。(单词字符是a-zA-Z1-9_)

自从 | 代表正则表达式中的交替运算符,您将不得不对其进行转义。

所以正则表达式\bfoo\b会匹配foofoo|bar因为 | 是一个非单词字符。无需使用字符集[\b\|]

编辑:正如弗洛德尔在 \b 下面指出的,字符集中代表退格字符。所以它会匹配 | 在 [\b\|] 而不是单词边界内。

于 2012-10-14T19:00:47.820 回答
1

由于|在正则表达式中具有特殊含义,因此您需要对其进行转义,即使用\\|

ptn <- "\\bfoo[\\|\\b]"

grep(ptn, "foo|baz|bar") 
[1] 1

grep(ptn, "foo")          
integer(0)
于 2012-10-14T18:40:36.207 回答
0

这也可以:

gregexpr("foo|", "foo|baz|bar", fixed = TRUE)[[c(1, 1)]] > 0
gregexpr("foo|", "foobaz|bar", fixed = TRUE)[[c(1, 1)]] > 0    
gregexpr("foo|", "bazfoo", fixed = TRUE)[[c(1, 1)]] > 0 

这种方法的不同之处在于您可以利用您提供的间距选项gregexpr来查找由两个单词组成的单词:

gregexpr("foo|", "baz foo|", fixed = TRUE)[[c(1, 1)]] > 0 
gregexpr("  foo|", "baz foo|", fixed = TRUE)[[c(1, 1)]] > 0 
于 2012-10-14T18:50:17.260 回答