2012-10-14 40 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 
相關問題