2012-10-14 45 views
1

假设有一个形式为"foo""foo|baz|bar"(单个单词或多个单词用"|"之类的特殊字符分隔的单词)的向量,我们也给出了一个单词,我们希望找到它向量中的哪个项目有全字匹配。R grep用特殊字符分隔的整个单词

例如字"foo"具有"foo|baz|bar"一个整体匹配,而不是在任一"foobaz|bar""bazfoo"一个整体匹配。

首先,我试图用"\\b"指示开始或整个单词的末尾边缘和它的作品成功:

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

然后我试图添加"|"为两端的其他可能的分离器,与"\\b"组使用它和[]

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""foo2"

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

+0

对我来说很难选择正确的答案,因为他们中的大多数都非常完美! – Ali

回答

2

\ b会与以下位置

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

由于|代表正则表达式中的交替操作符,你将不得不逃脱它。

所以正则表达式\bfoo\b匹配foofoo|bar,因为|是一个非单词字符。没有必要使用字符集[\b\|]

编辑:由于在字符集内的\ b指出的flodel表示退格字符。所以它会匹配|在[\ b \ |]里面,而不是字边界。

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 
+0

谢谢,但我更感兴趣知道为什么grep(“[| \\ b] foo [| \\ b]”,“foo”)不匹配? – Ali

+0

因为你需要转义'|'。出于同样的原因,我选择在'strsplit'内部使用'fixed = TRUE'。 – flodel

+0

如果我只查看**“**”作为分隔符,“\\ b”不是一个好选择,所以你的回答在这种情况下似乎更好 – Ali

1

由于|正则表达式中具有特殊的意义,你需要逃避它,即使用\\|

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

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

grep(ptn, "foo")   
integer(0) 
+0

感谢您的好评。我发现即使“\\ bfoo \\ b”也适合我的目标。你认为需要改进你的答案吗? – Ali

+0

@AliSharifi如果您想优化我的答案,请继续。我相信我已经回复你的问题。 – Andrie

+0

这里有趣的是:'grep(“afooa”,“afooa”)'给出了一个匹配。 'grep(“[a] foo [a]”,“afooa”)''也是如此。所以'grep(“\\ bfoo \\ b”,“foo”)',但不是'grep(“[\\ b] foo [\\ b]”,“foo”)'。任何想法? – flodel

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 
相关问题