2012-03-02 278 views
26

在R中,grep通常匹配多個字符串對一個正則表達式的向量。R grep:匹配多個模式的一個字符串

問:是否有可能將單個字符串與多個正則表達式匹配? (沒有循環遍歷每一個正則表達式模式)?

一些背景資料:

我有7000+的關鍵詞作爲指標的幾個類別。我無法更改該關鍵字字典。這本字典有以下結構(關鍵字在第1欄的數字代表這些關鍵字屬於類別):

ab 10 37 41 
abbrach* 38 
abbreche 39 
abbrich* 39 
abend* 37 
abendessen* 60 63 
aber 20 23 45 
abermals 37 

串聯有這麼多的關鍵字「|」不是一個可行的方法(我不知道哪個關鍵字產生了命中)。 此外,只是反轉「模式」和「字符串」不起作用,因爲模式具有截斷,這不會反過來工作。

[related question,其他編程語言]

+2

我就像丹的建議一樣,但是對於大數據集,您可能會遇到一些重大的速度問題。如果您想在字典中查找某些內容並返回對應的值,我會建議採用不同的方法:使用strsplit將句子分解爲單個單詞的向量,然後應用哈希表進行快速查找。我在想,你可能想把關鍵字和類別指標分成兩個單獨的字典列。我會在那裏提供幫助,但只有在你更清楚地將最終結果作爲想要之後。 – 2012-03-02 18:33:04

+0

同意重構字典數據並使用散列表進行查找(取決於期望的結果),但匹配應該相對較快,具體取決於字符串的數量,即使使用大量關鍵字也是如此。我會爲我的答案添加一個快速基準。 – danpelota 2012-03-02 19:33:03

+1

如果你真的有很多單詞 (通常是人類語言中的所有單詞, 所有被google索引的單詞等),你可以使用 [前綴樹](http:// en。 wikipedia.org/wiki/Trie) (它有時也被稱爲「trie」)。 但我不知道任何實現的R. – 2012-03-02 23:25:46

回答

28

怎麼樣了關鍵字的矢量應用regexpr功能?返回

keywords <- c("dog", "cat", "bird") 

strings <- c("Do you have a dog?", "My cat ate by bird.", "Let's get icecream!") 

sapply(keywords, regexpr, strings, ignore.case=TRUE) 

    dog cat bird 
[1,] 15 -1 -1 
[2,] -1 4 15 
[3,] -1 -1 -1 

    sapply(keywords, regexpr, strings[1], ignore.case=TRUE) 

dog cat bird 
    15 -1 -1 

值是在比賽的第一個字符的位置,與-1意義不匹配。

如果匹配的位置是無關緊要的,使用grepl代替:

sapply(keywords, grepl, strings, ignore.case=TRUE) 

     dog cat bird 
[1,] TRUE FALSE FALSE 
[2,] FALSE TRUE TRUE 
[3,] FALSE FALSE FALSE 

更新:這將運行在我的系統比較快,即使有大量的關鍵字:

# Available on most *nix systems 
words <- scan("/usr/share/dict/words", what="") 
length(words) 
[1] 234936 

system.time(matches <- sapply(words, grepl, strings, ignore.case=TRUE)) 

    user system elapsed 
    7.495 0.155 7.596 

dim(matches) 
[1]  3 234936 
+0

謝謝您的回答與您的意見!最後,我做了一個綜合的方法:將一組可能的匹配減少到原始大小的〜5%,並且sapply函數完成了grep。 – 2012-03-05 10:13:31

+0

然後爲了查看每個句子/字符串中有多少個關鍵字與最終數據幀匹配,問題: num.matches < - apply(data.frame(matches),1,function(z)sum( ž== TRUE)) 。並且查找哪個原始字符串有,比方說,2個匹配,問題: strings [num.matches == 2]#輸出:[1]「我的貓吃了鳥。」 – 2014-04-05 11:41:34

+0

如果你想做一個替代品,你不只是閱讀關鍵字來搜索,而且他們的替代品? – user1603472 2017-08-11 11:31:03

2

要擴展other answer,要將sapply()輸出轉換爲有用的邏輯向量,您需要進一步使用apply()步驟。

keywords <- c("dog", "cat", "bird") 
strings <- c("Do you have a dog?", "My cat ate by bird.", "Let's get icecream!") 
(matches <- sapply(keywords, grepl, strings, ignore.case=TRUE)) 
#  dog cat bird 
# [1,] TRUE FALSE FALSE 
# [2,] FALSE TRUE TRUE 
# [3,] FALSE FALSE FALSE 

要知道哪些字符串包含關鍵字的任何(模式):

apply(matches, 1, any) 
# [1] TRUE TRUE FALSE 

要知道哪些關鍵字(模式)中提供的字符串相匹配:

apply(matches, 2, any) 
# dog cat bird 
# TRUE TRUE TRUE